From 43a6d2c3a2ac6c6f51e75938954428d007d7df72 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Thu, 1 Sep 2022 15:03:20 +0200 Subject: [PATCH 01/10] Start to write e2e tests --- Cargo.lock | 1 + Cargo.toml | 5 +- src/base/cert_utils.rs | 6 +- src/lib.rs | 3 + src/tcp_relay_client/client_config.rs | 55 +++--- src/tcp_relay_server/server_config.rs | 2 +- src/test/dummy_tcp_sockets.rs | 250 ++++++++++++++++++++++++++ src/test/mod.rs | 15 ++ src/test/valid_with_token_auth.rs | 61 +++++++ 9 files changed, 369 insertions(+), 29 deletions(-) create mode 100644 src/test/dummy_tcp_sockets.rs create mode 100644 src/test/mod.rs create mode 100644 src/test/valid_with_token_auth.rs diff --git a/Cargo.lock b/Cargo.lock index a4d754d..facd298 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1603,6 +1603,7 @@ dependencies = [ "hyper-rustls", "log", "pem", + "rand", "reqwest", "rustls", "rustls-pemfile", diff --git a/Cargo.toml b/Cargo.toml index 4a1925e..a789475 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,4 +24,7 @@ urlencoding = "2.1.0" hyper-rustls = { version = "0.23.0", features = ["rustls-native-certs"] } bytes = "1.2.1" rustls-pemfile = "1.0.1" -rustls = "0.20.6" \ No newline at end of file +rustls = "0.20.6" + +[dev-dependencies] +rand = "0.8.5" \ No newline at end of file diff --git a/src/base/cert_utils.rs b/src/base/cert_utils.rs index 620de2d..9dac6c9 100644 --- a/src/base/cert_utils.rs +++ b/src/base/cert_utils.rs @@ -50,10 +50,10 @@ pub fn parse_pem_private_key(privkey: &[u8]) -> Result, - #[clap(skip)] - _root_certificate_cache: Option>, - /// TLS certificate for TLS authentication. #[clap(long)] pub tls_cert: Option, - #[clap(skip)] - _tls_cert_cache: Option>, - /// TLS key for TLS authentication. #[clap(long)] pub tls_key: Option, + #[clap(skip)] + pub _keys_cache: KeysCache, +} + +#[derive(Parser, Debug, Clone, Default)] +pub struct KeysCache { + #[clap(skip)] + _root_certificate_cache: Option>, + #[clap(skip)] + _tls_cert_cache: Option>, #[clap(skip)] _tls_key_cache: Option>, } @@ -42,20 +46,20 @@ pub struct ClientConfig { impl ClientConfig { /// Load certificates and put them in cache pub fn load_certificates(&mut self) { - self._root_certificate_cache = self - .root_certificate - .as_ref() - .map(|c| std::fs::read(c).expect("Failed to read root certificate!")); - - self._tls_cert_cache = self - .tls_cert - .as_ref() - .map(|c| std::fs::read(c).expect("Failed to read client certificate!")); - - self._tls_key_cache = self - .tls_key - .as_ref() - .map(|c| std::fs::read(c).expect("Failed to read client key!")); + self._keys_cache = KeysCache { + _root_certificate_cache: self + .root_certificate + .as_ref() + .map(|c| std::fs::read(c).expect("Failed to read root certificate!")), + _tls_cert_cache: self + .tls_cert + .as_ref() + .map(|c| std::fs::read(c).expect("Failed to read client certificate!")), + _tls_key_cache: self + .tls_key + .as_ref() + .map(|c| std::fs::read(c).expect("Failed to read client key!")), + }; } /// Get client token, returning a dummy token if none was specified @@ -65,12 +69,15 @@ impl ClientConfig { /// Get root certificate content pub fn get_root_certificate(&self) -> Option> { - self._root_certificate_cache.clone() + self._keys_cache._root_certificate_cache.clone() } /// Get client certificate & key pair, if available pub fn get_client_keypair(&self) -> Option<(&Vec, &Vec)> { - if let (Some(cert), Some(key)) = (&self._tls_cert_cache, &self._tls_key_cache) { + if let (Some(cert), Some(key)) = ( + &self._keys_cache._tls_cert_cache, + &self._keys_cache._tls_key_cache, + ) { Some((cert, key)) } else { None @@ -90,7 +97,7 @@ impl ClientConfig { #[cfg(test)] mod test { - use crate::client_config::ClientConfig; + use crate::tcp_relay_client::client_config::ClientConfig; #[test] fn verify_cli() { diff --git a/src/tcp_relay_server/server_config.rs b/src/tcp_relay_server/server_config.rs index 838ca40..9e3e94d 100644 --- a/src/tcp_relay_server/server_config.rs +++ b/src/tcp_relay_server/server_config.rs @@ -74,7 +74,7 @@ impl ServerConfig { #[cfg(test)] mod test { - use crate::server_config::ServerConfig; + use crate::tcp_relay_server::server_config::ServerConfig; #[test] fn verify_cli() { diff --git a/src/test/dummy_tcp_sockets.rs b/src/test/dummy_tcp_sockets.rs new file mode 100644 index 0000000..348a5cd --- /dev/null +++ b/src/test/dummy_tcp_sockets.rs @@ -0,0 +1,250 @@ +use std::time::Duration; + +use rand::Rng; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::{TcpListener, TcpStream}; +use tokio::time; + +use crate::test::LOCALHOST; + +pub struct DummyTCPServer(TcpListener); + +impl DummyTCPServer { + pub async fn start(port: u16) -> Self { + let addr = format!("{}:{}", LOCALHOST, port); + println!("[DUMMY TCP] Listen on {}", addr); + let listener = TcpListener::bind(addr) + .await + .expect("Failed to bind dummy TCP listener!"); + Self(listener) + } + + /// Receive chunk of data from following connection + pub async fn read_next_connection(&self) -> Vec { + let (mut conn, _addr) = self + .0 + .accept() + .await + .expect("Could not open next connection!"); + + let mut buff = Vec::with_capacity(100); + conn.read_to_end(&mut buff).await.unwrap(); + + buff + } + + /// Receive chunk of data from following connection + pub async fn read_then_write_next_connection(&self, to_send: &[u8]) -> Vec { + let (mut conn, _addr) = self + .0 + .accept() + .await + .expect("Could not open next connection!"); + + let mut buff: [u8; 100] = [0; 100]; + let size = conn.read(&mut buff).await.unwrap(); + + conn.write_all(to_send).await.unwrap(); + + buff[0..size].to_vec() + } + + /// Receive chunk of data from following connection + pub async fn write_next_connection(&self, to_send: &[u8]) { + let (mut conn, _addr) = self + .0 + .accept() + .await + .expect("Could not open next connection!"); + + conn.write_all(to_send).await.unwrap() + } + + /// Perform complex exchange: receive numbers from client and respond with their square + pub async fn next_conn_square_operations(&self) { + let (mut conn, _addr) = self + .0 + .accept() + .await + .expect("Could not open next connection!"); + + let mut buff: [u8; 100] = [0; 100]; + loop { + let size = conn.read(&mut buff).await.unwrap(); + if size == 0 { + break; + } + + let content = String::from_utf8_lossy(&buff[0..size]) + .to_string() + .parse::() + .unwrap(); + + conn.write_all((content * content).to_string().as_bytes()) + .await + .unwrap(); + } + } +} + +pub async fn dummy_tcp_client_read_conn(port: u16) -> Vec { + let mut socket = TcpStream::connect(format!("127.0.0.1:{}", port)) + .await + .expect("Failed to connect to dummy TCP server!"); + + let mut buff = Vec::with_capacity(100); + socket.read_to_end(&mut buff).await.unwrap(); + + buff +} + +pub async fn dummy_tcp_client_write_then_read_conn(port: u16, data: &[u8]) -> Vec { + let mut socket = TcpStream::connect(format!("127.0.0.1:{}", port)) + .await + .expect("Failed to connect to dummy TCP server!"); + + socket.write_all(data).await.unwrap(); + + let mut buff: [u8; 100] = [0; 100]; + let size = socket.read(&mut buff).await.unwrap(); + + buff[0..size].to_vec() +} + +pub async fn dummy_tcp_client_write_conn(port: u16, data: &[u8]) { + let mut socket = TcpStream::connect(format!("127.0.0.1:{}", port)) + .await + .expect("Failed to connect to dummy TCP server!"); + + socket.write_all(data).await.unwrap() +} + +pub async fn dummy_tcp_client_square_root_requests(port: u16, num_exchanges: usize) { + let mut socket = TcpStream::connect(format!("127.0.0.1:{}", port)) + .await + .expect("Failed to connect to dummy TCP server!"); + + let mut rng = rand::thread_rng(); + let mut buff: [u8; 100] = [0; 100]; + + for _ in 0..num_exchanges { + let num = rng.gen::() % 100; + socket.write_all(num.to_string().as_bytes()).await.unwrap(); + + let size = socket.read(&mut buff).await.unwrap(); + + if size == 0 { + panic!("Got empty response!"); + } + + let got = String::from_utf8_lossy(&buff[0..size]) + .to_string() + .parse::() + .unwrap(); + println!("{} * {} = {} (based on server response)", num, num, got); + assert_eq!((num * num) as i64, got); + } +} + +/// Check whether a given port is open or not +pub async fn is_port_open(port: u16) -> bool { + match TcpStream::connect(("127.0.0.1", port)).await { + Ok(_) => true, + Err(_) => false, + } +} + +/// Wait for a port to become available +pub async fn wait_for_port(port: u16) { + for _ in 0..50 { + if is_port_open(port).await { + return; + } + time::sleep(Duration::from_millis(10)).await; + } + + eprintln!("Port {} did not open in time!", port); + std::process::exit(2); +} + +mod test { + use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_read_conn, dummy_tcp_client_square_root_requests, + dummy_tcp_client_write_conn, dummy_tcp_client_write_then_read_conn, DummyTCPServer, + }; + use crate::test::{get_port_number, PortsAllocation}; + + fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::DummyTCPServer, index) + } + + #[tokio::test] + async fn socket_read_from_server() { + const DATA: &[u8] = "Hello world!!!".as_bytes(); + + let listener = DummyTCPServer::start(port(0)).await; + let handle = tokio::spawn(async move { + listener.write_next_connection(DATA).await; + }); + let data = dummy_tcp_client_read_conn(port(0)).await; + assert_eq!(data, DATA); + + handle.await.unwrap(); + } + + #[tokio::test] + async fn socket_write_to_server() { + const DATA: &[u8] = "Hello world 2".as_bytes(); + + let listener = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + dummy_tcp_client_write_conn(port(1), DATA).await; + }); + let data = listener.read_next_connection().await; + assert_eq!(data, DATA); + } + + #[tokio::test] + async fn socket_read_and_write_to_server() { + const DATA_1: &[u8] = "Hello world 3a".as_bytes(); + const DATA_2: &[u8] = "Hello world 3b".as_bytes(); + + let listener = DummyTCPServer::start(port(2)).await; + let handle = tokio::spawn(async move { + println!("client handle"); + let data = dummy_tcp_client_write_then_read_conn(port(2), DATA_1).await; + assert_eq!(data, DATA_2); + }); + let h2 = tokio::spawn(async move { + println!("server handle"); + let data = listener.read_then_write_next_connection(DATA_2).await; + assert_eq!(data, DATA_1); + }); + + handle.await.unwrap(); + h2.await.unwrap(); + } + + #[tokio::test] + async fn socket_dummy_root_calculator() { + let listener = DummyTCPServer::start(port(3)).await; + let handle = tokio::spawn(async move { + listener.next_conn_square_operations().await; + }); + let data = dummy_tcp_client_write_then_read_conn(port(3), "5".as_bytes()).await; + assert_eq!(data, "25".as_bytes()); + + handle.await.unwrap(); + } + + #[tokio::test] + async fn socket_dummy_root_calculator_multiple() { + let listener = DummyTCPServer::start(port(4)).await; + let handle = tokio::spawn(async move { + listener.next_conn_square_operations().await; + }); + dummy_tcp_client_square_root_requests(port(4), 10).await; + + handle.await.unwrap(); + } +} diff --git a/src/test/mod.rs b/src/test/mod.rs new file mode 100644 index 0000000..cc0f23b --- /dev/null +++ b/src/test/mod.rs @@ -0,0 +1,15 @@ +#[non_exhaustive] +enum PortsAllocation { + DummyTCPServer, + ValidWithTokenAuth, +} + +fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { + 2100 + 20 * (alloc as u16) + index +} + +const LOCALHOST: &str = "127.0.0.1"; + +mod dummy_tcp_sockets; + +mod valid_with_token_auth; diff --git a/src/test/valid_with_token_auth.rs b/src/test/valid_with_token_auth.rs new file mode 100644 index 0000000..da3aba6 --- /dev/null +++ b/src/test/valid_with_token_auth.rs @@ -0,0 +1,61 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_square_root_requests, dummy_tcp_client_write_then_read_conn, wait_for_port, + DummyTCPServer, +}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +const DATA_1: &[u8] = "DATA1".as_bytes(); +const DATA_2: &[u8] = "DATA2".as_bytes(); + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidWithTokenAuth, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn valid_with_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + tokio::spawn(async move { + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + local_server.next_conn_square_operations().await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("http://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + })); + wait_for_port(port(2)).await; + }) + .await; +} -- 2.45.2 From 62fa71ea6eb38c9527d5b289161918a803752f38 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Thu, 1 Sep 2022 17:05:13 +0200 Subject: [PATCH 02/10] Check the case with invalid token --- src/tcp_relay_client/mod.rs | 20 ++++++---- src/test/dummy_tcp_sockets.rs | 6 +++ src/test/invalid_with_token_auth.rs | 57 +++++++++++++++++++++++++++++ src/test/mod.rs | 2 + src/test/valid_with_token_auth.rs | 14 +++---- 5 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 src/test/invalid_with_token_auth.rs diff --git a/src/tcp_relay_client/mod.rs b/src/tcp_relay_client/mod.rs index 8010952..6ca6424 100644 --- a/src/tcp_relay_client/mod.rs +++ b/src/tcp_relay_client/mod.rs @@ -1,6 +1,7 @@ extern crate core; use std::error::Error; +use std::io::ErrorKind; use std::sync::Arc; use futures::future::join_all; @@ -39,11 +40,13 @@ async fn get_server_config(conf: &ClientConfig) -> Result().await?) @@ -70,8 +73,11 @@ pub async fn run_app(mut args: ClientConfig) -> std::io::Result<()> { let remote_conf = match get_server_config(&args).await { Ok(c) => c, Err(e) => { - log::error!("Failed to fetch relay configuration from server! {}", e); - panic!(); + Err(std::io::Error::new( + ErrorKind::Other, + format!("Failed to fetch relay configuration from server! {}", e), + ))?; + unreachable!(); } }; diff --git a/src/test/dummy_tcp_sockets.rs b/src/test/dummy_tcp_sockets.rs index 348a5cd..03262f5 100644 --- a/src/test/dummy_tcp_sockets.rs +++ b/src/test/dummy_tcp_sockets.rs @@ -85,6 +85,12 @@ impl DummyTCPServer { .unwrap(); } } + + pub async fn loop_conn_square_operations(&self) { + loop { + self.next_conn_square_operations().await + } + } } pub async fn dummy_tcp_client_read_conn(port: u16) -> Vec { diff --git a/src/test/invalid_with_token_auth.rs b/src/test/invalid_with_token_auth.rs new file mode 100644 index 0000000..75ed953 --- /dev/null +++ b/src/test/invalid_with_token_auth.rs @@ -0,0 +1,57 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; +const INVALID_TOKEN: &str = "AnInvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::InvalidWithTokenAuth, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn invalid_with_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + tokio::spawn(async move { + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + local_server.loop_conn_square_operations().await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(INVALID_TOKEN.to_string()), + relay_url: format!("http://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} diff --git a/src/test/mod.rs b/src/test/mod.rs index cc0f23b..fd8d92c 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -2,6 +2,7 @@ enum PortsAllocation { DummyTCPServer, ValidWithTokenAuth, + InvalidWithTokenAuth, } fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { @@ -12,4 +13,5 @@ const LOCALHOST: &str = "127.0.0.1"; mod dummy_tcp_sockets; +mod invalid_with_token_auth; mod valid_with_token_auth; diff --git a/src/test/valid_with_token_auth.rs b/src/test/valid_with_token_auth.rs index da3aba6..bbdb7c9 100644 --- a/src/test/valid_with_token_auth.rs +++ b/src/test/valid_with_token_auth.rs @@ -3,16 +3,12 @@ use tokio::task; use crate::tcp_relay_client::client_config::ClientConfig; use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{ - dummy_tcp_client_square_root_requests, dummy_tcp_client_write_then_read_conn, wait_for_port, - DummyTCPServer, + dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, }; use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; const VALID_TOKEN: &str = "AvalidTOKEN"; -const DATA_1: &[u8] = "DATA1".as_bytes(); -const DATA_2: &[u8] = "DATA2".as_bytes(); - fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidWithTokenAuth, index) } @@ -21,10 +17,10 @@ fn port(index: u16) -> u16 { async fn valid_with_token_auth() { let _ = env_logger::builder().is_test(true).try_init(); + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; tokio::spawn(async move { - // Start internal service - let local_server = DummyTCPServer::start(port(1)).await; - local_server.next_conn_square_operations().await; + local_server.loop_conn_square_operations().await; }); let local_set = task::LocalSet::new(); @@ -56,6 +52,8 @@ async fn valid_with_token_auth() { ..Default::default() })); wait_for_port(port(2)).await; + + dummy_tcp_client_square_root_requests(port(2), 10).await; }) .await; } -- 2.45.2 From 886843d08738c427761ebedf167dbee31860779d Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 08:59:07 +0200 Subject: [PATCH 03/10] Add new test based on token auth --- Cargo.lock | 19 ++++ Cargo.toml | 3 +- src/base/err_utils.rs | 7 ++ src/base/mod.rs | 1 + src/tcp_relay_server/mod.rs | 4 +- .../client_try_tls_while_there_is_no_tls.rs | 55 ++++++++++++ src/test/dummy_tcp_sockets.rs | 87 ++++++++++++++++++- src/test/invalid_token_file.rs | 28 ++++++ src/test/mod.rs | 12 +++ src/test/valid_token_with_custom_increment.rs | 59 +++++++++++++ src/test/valid_with_multiple_token_auth.rs | 63 ++++++++++++++ .../valid_with_token_auth_multiple_ports.rs | 67 ++++++++++++++ src/test/valid_with_token_file.rs | 62 +++++++++++++ 13 files changed, 462 insertions(+), 5 deletions(-) create mode 100644 src/base/err_utils.rs create mode 100644 src/test/client_try_tls_while_there_is_no_tls.rs create mode 100644 src/test/invalid_token_file.rs create mode 100644 src/test/valid_token_with_custom_increment.rs create mode 100644 src/test/valid_with_multiple_token_auth.rs create mode 100644 src/test/valid_with_token_auth_multiple_ports.rs create mode 100644 src/test/valid_with_token_file.rs diff --git a/Cargo.lock b/Cargo.lock index facd298..7e6f235 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1042,6 +1042,15 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "mktemp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975de676448231fcde04b9149d2543077e166b78fc29eae5aa219e7928410da2" +dependencies = [ + "uuid", +] + [[package]] name = "nom" version = "7.1.1" @@ -1602,6 +1611,7 @@ dependencies = [ "futures", "hyper-rustls", "log", + "mktemp", "pem", "rand", "reqwest", @@ -1873,6 +1883,15 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", +] + [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index a789475..ff673c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,5 @@ rustls-pemfile = "1.0.1" rustls = "0.20.6" [dev-dependencies] -rand = "0.8.5" \ No newline at end of file +rand = "0.8.5" +mktemp = "0.4.1" \ No newline at end of file diff --git a/src/base/err_utils.rs b/src/base/err_utils.rs new file mode 100644 index 0000000..d9c10a7 --- /dev/null +++ b/src/base/err_utils.rs @@ -0,0 +1,7 @@ +use std::error::Error; +use std::io::ErrorKind; + +/// Encapsulate errors in [`std::io::Error`] with a message +pub fn encpasulate_error(e: E, msg: &str) -> std::io::Error { + std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg, e)) +} diff --git a/src/base/mod.rs b/src/base/mod.rs index c09934b..b908837 100644 --- a/src/base/mod.rs +++ b/src/base/mod.rs @@ -1,4 +1,5 @@ pub mod cert_utils; +pub mod err_utils; mod structs; pub use structs::{RelayedPort, RemoteConfig}; diff --git a/src/tcp_relay_server/mod.rs b/src/tcp_relay_server/mod.rs index aefea39..8905c72 100644 --- a/src/tcp_relay_server/mod.rs +++ b/src/tcp_relay_server/mod.rs @@ -3,8 +3,8 @@ use std::sync::Arc; use actix_web::web::Data; use actix_web::{middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder}; +use crate::base::err_utils::encpasulate_error; use crate::base::{cert_utils, RelayedPort}; - use crate::tcp_relay_server::relay_ws::relay_ws; use crate::tcp_relay_server::server_config::ServerConfig; use crate::tcp_relay_server::tls_cert_client_verifier::CustomCertClientVerifier; @@ -54,7 +54,7 @@ pub async fn run_app(mut config: ServerConfig) -> std::io::Result<()> { // Read tokens from file, if any if let Some(file) = &config.tokens_file { std::fs::read_to_string(file) - .expect("Failed to read tokens file!") + .map_err(|e| encpasulate_error(e, "Failed to read tokens file!"))? .split('\n') .filter(|l| !l.is_empty()) .for_each(|t| config.tokens.push(t.to_string())); diff --git a/src/test/client_try_tls_while_there_is_no_tls.rs b/src/test/client_try_tls_while_there_is_no_tls.rs new file mode 100644 index 0000000..73590eb --- /dev/null +++ b/src/test/client_try_tls_while_there_is_no_tls.rs @@ -0,0 +1,55 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ClientTryTLSWhileThereIsNoTLS, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn valid_with_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} diff --git a/src/test/dummy_tcp_sockets.rs b/src/test/dummy_tcp_sockets.rs index 03262f5..8b36ee2 100644 --- a/src/test/dummy_tcp_sockets.rs +++ b/src/test/dummy_tcp_sockets.rs @@ -91,6 +91,38 @@ impl DummyTCPServer { self.next_conn_square_operations().await } } + + /// Perform complex exchange: receive numbers from client and respond with their value + a given number + pub async fn next_conn_add_operations(&self, inc: i32) { + let (mut conn, _addr) = self + .0 + .accept() + .await + .expect("Could not open next connection!"); + + let mut buff: [u8; 100] = [0; 100]; + loop { + let size = conn.read(&mut buff).await.unwrap(); + if size == 0 { + break; + } + + let content = String::from_utf8_lossy(&buff[0..size]) + .to_string() + .parse::() + .unwrap(); + + conn.write_all((content + inc as i64).to_string().as_bytes()) + .await + .unwrap(); + } + } + + pub async fn loop_next_conn_add_operations(&self, inc: i32) { + loop { + self.next_conn_add_operations(inc).await + } + } } pub async fn dummy_tcp_client_read_conn(port: u16) -> Vec { @@ -152,6 +184,33 @@ pub async fn dummy_tcp_client_square_root_requests(port: u16, num_exchanges: usi } } +pub async fn dummy_tcp_client_additions_requests(port: u16, inc: i32, num_exchanges: usize) { + let mut socket = TcpStream::connect(format!("127.0.0.1:{}", port)) + .await + .expect("Failed to connect to dummy TCP server!"); + + let mut rng = rand::thread_rng(); + let mut buff: [u8; 100] = [0; 100]; + + for _ in 0..num_exchanges { + let num = rng.gen::() % 100; + socket.write_all(num.to_string().as_bytes()).await.unwrap(); + + let size = socket.read(&mut buff).await.unwrap(); + + if size == 0 { + panic!("Got empty response!"); + } + + let got = String::from_utf8_lossy(&buff[0..size]) + .to_string() + .parse::() + .unwrap(); + println!("{} + {} = {} (based on server response)", num, inc, got); + assert_eq!((num + inc) as i64, got); + } +} + /// Check whether a given port is open or not pub async fn is_port_open(port: u16) -> bool { match TcpStream::connect(("127.0.0.1", port)).await { @@ -175,8 +234,9 @@ pub async fn wait_for_port(port: u16) { mod test { use crate::test::dummy_tcp_sockets::{ - dummy_tcp_client_read_conn, dummy_tcp_client_square_root_requests, - dummy_tcp_client_write_conn, dummy_tcp_client_write_then_read_conn, DummyTCPServer, + dummy_tcp_client_additions_requests, dummy_tcp_client_read_conn, + dummy_tcp_client_square_root_requests, dummy_tcp_client_write_conn, + dummy_tcp_client_write_then_read_conn, DummyTCPServer, }; use crate::test::{get_port_number, PortsAllocation}; @@ -253,4 +313,27 @@ mod test { handle.await.unwrap(); } + + #[tokio::test] + async fn socket_dummy_addition_calculator() { + let listener = DummyTCPServer::start(port(5)).await; + let handle = tokio::spawn(async move { + listener.next_conn_add_operations(4).await; + }); + let data = dummy_tcp_client_write_then_read_conn(port(5), "5".as_bytes()).await; + assert_eq!(data, "9".as_bytes()); + + handle.await.unwrap(); + } + + #[tokio::test] + async fn socket_dummy_addition_calculator_multiple() { + let listener = DummyTCPServer::start(port(6)).await; + let handle = tokio::spawn(async move { + listener.next_conn_add_operations(7).await; + }); + dummy_tcp_client_additions_requests(port(6), 7, 10).await; + + handle.await.unwrap(); + } } diff --git a/src/test/invalid_token_file.rs b/src/test/invalid_token_file.rs new file mode 100644 index 0000000..b16b7c0 --- /dev/null +++ b/src/test/invalid_token_file.rs @@ -0,0 +1,28 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::{get_port_number, PortsAllocation}; + +const INVALID_TOKEN: &str = "/tmp/a/token/file/that/does/not/exists"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::InvalidTokenFile, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn invalid_with_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: Some(INVALID_TOKEN.to_string()), + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/mod.rs b/src/test/mod.rs index fd8d92c..9135a92 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -3,6 +3,12 @@ enum PortsAllocation { DummyTCPServer, ValidWithTokenAuth, InvalidWithTokenAuth, + ValidWithMultipleTokenAuth, + ValidWithTokenFile, + InvalidTokenFile, + ClientTryTLSWhileThereIsNoTLS, + ValidTokenWithCustomIncrement, + ValidWithTokenAuthMultiplePorts, } fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { @@ -13,5 +19,11 @@ const LOCALHOST: &str = "127.0.0.1"; mod dummy_tcp_sockets; +mod client_try_tls_while_there_is_no_tls; +mod invalid_token_file; mod invalid_with_token_auth; +mod valid_token_with_custom_increment; +mod valid_with_multiple_token_auth; mod valid_with_token_auth; +mod valid_with_token_auth_multiple_ports; +mod valid_with_token_file; diff --git a/src/test/valid_token_with_custom_increment.rs b/src/test/valid_token_with_custom_increment.rs new file mode 100644 index 0000000..c466b74 --- /dev/null +++ b/src/test/valid_token_with_custom_increment.rs @@ -0,0 +1,59 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, +}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidTokenWithCustomIncrement, index) +} + +#[tokio::test(flavor = "multi_thread")] +async fn valid_with_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 3, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("http://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + })); + wait_for_port(port(4)).await; + + dummy_tcp_client_square_root_requests(port(4), 10).await; + }) + .await; +} diff --git a/src/test/valid_with_multiple_token_auth.rs b/src/test/valid_with_multiple_token_auth.rs new file mode 100644 index 0000000..5b03c2e --- /dev/null +++ b/src/test/valid_with_multiple_token_auth.rs @@ -0,0 +1,63 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, +}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidWithTokenFile, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn valid_with_multiple_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![ + "tok0".to_string(), + VALID_TOKEN.to_string(), + "tok2".to_string(), + ], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("http://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + })); + wait_for_port(port(2)).await; + + dummy_tcp_client_square_root_requests(port(2), 10).await; + }) + .await; +} diff --git a/src/test/valid_with_token_auth_multiple_ports.rs b/src/test/valid_with_token_auth_multiple_ports.rs new file mode 100644 index 0000000..fc68f4f --- /dev/null +++ b/src/test/valid_with_token_auth_multiple_ports.rs @@ -0,0 +1,67 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_additions_requests, dummy_tcp_client_square_root_requests, wait_for_port, + DummyTCPServer, +}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; +const NUM_INC: i32 = 5; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidWithTokenAuthMultiplePorts, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn valid_with_token_auth() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal services + let local_server_1 = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server_1.loop_conn_square_operations().await; + }); + + let local_server_2 = DummyTCPServer::start(port(3)).await; + tokio::spawn(async move { + local_server_2.loop_next_conn_add_operations(NUM_INC).await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1), port(3)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("http://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + })); + wait_for_port(port(2)).await; + + dummy_tcp_client_square_root_requests(port(2), 10).await; + dummy_tcp_client_additions_requests(port(4), NUM_INC, 10).await; + }) + .await; +} diff --git a/src/test/valid_with_token_file.rs b/src/test/valid_with_token_file.rs new file mode 100644 index 0000000..e411afe --- /dev/null +++ b/src/test/valid_with_token_file.rs @@ -0,0 +1,62 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, +}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidWithMultipleTokenAuth, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn valid_with_token_file() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + let token_file = mktemp::Temp::new_file().unwrap(); + std::fs::write(&token_file, format!("tok1\ntok2\n{}\ntok4", VALID_TOKEN)).unwrap(); + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: Some(token_file.to_str().unwrap().to_string()), + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("http://{}:{}", LOCALHOST, port(0)), + listen_address: LOCALHOST.to_string(), + root_certificate: None, + ..Default::default() + })); + wait_for_port(port(2)).await; + + dummy_tcp_client_square_root_requests(port(2), 10).await; + }) + .await; +} -- 2.45.2 From 40c1bfc9386e630ee3f76747c736a5a964333e2a Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 09:43:07 +0200 Subject: [PATCH 04/10] Add new test based on token auth with TLS --- .gitignore | 2 - src/base/samples/TCPTunnelTest.crt | 29 +++++++++ src/base/samples/TCPTunnelTest.key | 51 +++++++++++++++ .../client_try_tls_while_there_is_no_tls.rs | 8 +-- src/test/dummy_tcp_sockets.rs | 4 +- src/test/invalid_token_file.rs | 2 +- src/test/invalid_with_token_auth.rs | 6 +- src/test/mod.rs | 10 ++- src/test/pki.rs | 53 ++++++++++++++++ src/test/test_files_utils.rs | 7 +++ src/test/test_pki/ExpiredClient.crt | 25 ++++++++ src/test/test_pki/ExpiredClient.key | 27 ++++++++ src/test/test_pki/OtherCA.crl | 16 +++++ src/test/test_pki/OtherCA.crt | 29 +++++++++ src/test/test_pki/OtherCA.key | 51 +++++++++++++++ src/test/test_pki/RevokedClient.crt | 25 ++++++++ src/test/test_pki/RevokedClient.key | 27 ++++++++ src/test/test_pki/TCPTunnelTestCA.crl | 17 +++++ src/test/test_pki/TCPTunnelTestCA.crt | 29 +++++++++ src/test/test_pki/TCPTunnelTestCA.key | 51 +++++++++++++++ src/test/test_pki/ValidClient.crt | 25 ++++++++ src/test/test_pki/ValidClient.key | 27 ++++++++ src/test/test_pki/localhost.crt | 25 ++++++++ src/test/test_pki/localhost.key | 27 ++++++++ src/test/valid_token_with_custom_increment.rs | 8 +-- src/test/valid_with_multiple_token_auth.rs | 6 +- src/test/valid_with_token_auth.rs | 6 +- .../valid_with_token_auth_and_server_tls.rs | 62 +++++++++++++++++++ .../valid_with_token_auth_multiple_ports.rs | 8 +-- src/test/valid_with_token_file.rs | 6 +- ...oken_auth_and_invalid_server_tls_bad_ca.rs | 54 ++++++++++++++++ ...d_invalid_server_tls_expired_and_bad_cn.rs | 54 ++++++++++++++++ 32 files changed, 747 insertions(+), 30 deletions(-) create mode 100644 src/base/samples/TCPTunnelTest.crt create mode 100644 src/base/samples/TCPTunnelTest.key create mode 100644 src/test/pki.rs create mode 100644 src/test/test_files_utils.rs create mode 100644 src/test/test_pki/ExpiredClient.crt create mode 100644 src/test/test_pki/ExpiredClient.key create mode 100644 src/test/test_pki/OtherCA.crl create mode 100644 src/test/test_pki/OtherCA.crt create mode 100644 src/test/test_pki/OtherCA.key create mode 100644 src/test/test_pki/RevokedClient.crt create mode 100644 src/test/test_pki/RevokedClient.key create mode 100644 src/test/test_pki/TCPTunnelTestCA.crl create mode 100644 src/test/test_pki/TCPTunnelTestCA.crt create mode 100644 src/test/test_pki/TCPTunnelTestCA.key create mode 100644 src/test/test_pki/ValidClient.crt create mode 100644 src/test/test_pki/ValidClient.key create mode 100644 src/test/test_pki/localhost.crt create mode 100644 src/test/test_pki/localhost.key create mode 100644 src/test/valid_with_token_auth_and_server_tls.rs create mode 100644 src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs create mode 100644 src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs diff --git a/.gitignore b/.gitignore index 0cab0fc..de6b1ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ target .idea -*.crt -*.key pki diff --git a/src/base/samples/TCPTunnelTest.crt b/src/base/samples/TCPTunnelTest.crt new file mode 100644 index 0000000..46c4a05 --- /dev/null +++ b/src/base/samples/TCPTunnelTest.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE8DCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDEw1UQ1BU +dW5uZWxUZXN0MB4XDTIyMDkwMTA2MzMyMFoXDTI0MDMwMTA2MzMxOFowGDEWMBQG +A1UEAxMNVENQVHVubmVsVGVzdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBALqh3EXg3TYq5TwZPjOX35bM7kol+fLlwjLaXCTx/lTXU0hTFsIa0kFCiPsT +Vhm5nwhDLxnAARagc74gUHfhr6meMbsje2NzylmCpW1As1s1xo2n8oNi2YsqIA9A +HWQWsihf7fPlyZOgBIwUQBsLd6ujpwbvaEhwBArS+peVYuB3zDbuNBJ2lqdvD5fa +8aCyoPyseaJcaMMJ3R2W/8OYrUsJECKgg26A8zxF55RdvjJcBONG0kRlNsrxS6uO +9dnQ8kyvUReluPgTEfZm/M54dCi9VvKVRKA/5md/+SQWwQhPyIig3+XXeYQNoUN6 +YXvlWw704VBg/hDBqrY42LjpS/FyMGsp4cHVCMXBLwRNHWPfik6w3rNTpFp7h4Mm +effxX2V/xuBr3IciVcsmeD4Xmfp0o6g3o5VPK4KIR5/b+aKe7uL8/9hTTLSqWpm8 ++k0boE796/gb8egyELwBrPsrdGQIiIP2Ac6m53iTtEtceIOmMB+t7mUPkQHsiLoC +LeRm2dbPWEKz2mO8fOVjVYT9nxY92l/AveuksTui5GZ2z4ZVp1m6pAxVjVf+L/Sg +MMkEfcIUW6Xb8Ba+KYRCc/5U8Xkz26F80dhjGdeledTpBhkyKqsxcKpLqFsuYj3W +b5FfLBlQe/Yargqd8HhvgMydi+lHG14FAflhp8emnOGOzaPbAgMBAAGjRTBDMA4G +A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTQ9A38 +JD46Si69hfW4me3CJZNK0DANBgkqhkiG9w0BAQsFAAOCAgEAIpNieyvlaO0E5oUz +1o7QJ+YtwwhPriOifrXAV+NaJj0n7Y1Fq4ztIhBPGtqwhPqgDUEn0G/mIr0BjA1w +/zQGJx1U8g9wNP8SERKVtD4Gx4S1ruLzTqK1V4xyV6bRhqmfi+YHNKviFNAEDDfz +rhiH1ULuoVfww8mH3FpL2oGhR+x900WkG98xtJ43ik/EIQu2kN+r5x9GPYC+NTC2 +xScVG3OGbJLE7fHDJBPSa5vOCk4DkBXKyOjYwnfd8Saz2E1u6w7eH3dgzCqiw66K +lcksjKD4+F1t4Jhy1p/K3qzZsZQ/NpHH9v++LATtwvUN2bzPLiZ/LhV5QH/kg9Qf +49OBRMKjUJ6MgQ7/JOwtaHyu8jBuJWUNEE47hpHGUrIxmLUi2AWlxxQZdPic+Rxf +LKWoNlGx5OrzcIuIc3lb11zinRdaawOjVV0yCKWIlSkb77Flp8WJIlZ6ZHLtqwsU +8D9zN4EXefc9dXYMLyWvRHmHOTr8430PebYc/G5BA+XjOgpFQ3vu8trIA/3Dbuyc +ggz1abiDnBmp+I66AYV+Ker81maM6CQU+03WKHbHZyJWr74SKuILY1knys/fXJvT +UZRMhmaQqxc1QcWVOkWLv0RcAhEjwIX0+36NUC1W35JfrRpHtmqIiJH9kjcjr94w +5sjM2EUFmMC5z0zjF9cSYKSHLSI= +-----END CERTIFICATE----- diff --git a/src/base/samples/TCPTunnelTest.key b/src/base/samples/TCPTunnelTest.key new file mode 100644 index 0000000..5afb737 --- /dev/null +++ b/src/base/samples/TCPTunnelTest.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/src/test/client_try_tls_while_there_is_no_tls.rs b/src/test/client_try_tls_while_there_is_no_tls.rs index 73590eb..c4e7b60 100644 --- a/src/test/client_try_tls_while_there_is_no_tls.rs +++ b/src/test/client_try_tls_while_there_is_no_tls.rs @@ -3,7 +3,7 @@ use tokio::task; use crate::tcp_relay_client::client_config::ClientConfig; use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; @@ -12,7 +12,7 @@ fn port(index: u16) -> u16 { } #[tokio::test(flavor = "multi_thread", worker_threads = 5)] -async fn valid_with_token_auth() { +async fn test() { let _ = env_logger::builder().is_test(true).try_init(); // Start internal service @@ -43,8 +43,8 @@ async fn valid_with_token_auth() { crate::tcp_relay_client::run_app(ClientConfig { token: Some(VALID_TOKEN.to_string()), - relay_url: format!("https://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() }) diff --git a/src/test/dummy_tcp_sockets.rs b/src/test/dummy_tcp_sockets.rs index 8b36ee2..69cfd36 100644 --- a/src/test/dummy_tcp_sockets.rs +++ b/src/test/dummy_tcp_sockets.rs @@ -5,13 +5,13 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; use tokio::time; -use crate::test::LOCALHOST; +use crate::test::LOCALHOST_IP; pub struct DummyTCPServer(TcpListener); impl DummyTCPServer { pub async fn start(port: u16) -> Self { - let addr = format!("{}:{}", LOCALHOST, port); + let addr = format!("{}:{}", LOCALHOST_IP, port); println!("[DUMMY TCP] Listen on {}", addr); let listener = TcpListener::bind(addr) .await diff --git a/src/test/invalid_token_file.rs b/src/test/invalid_token_file.rs index b16b7c0..b6f3564 100644 --- a/src/test/invalid_token_file.rs +++ b/src/test/invalid_token_file.rs @@ -8,7 +8,7 @@ fn port(index: u16) -> u16 { } #[tokio::test(flavor = "multi_thread", worker_threads = 5)] -async fn invalid_with_token_auth() { +async fn test() { let _ = env_logger::builder().is_test(true).try_init(); crate::tcp_relay_server::run_app(ServerConfig { diff --git a/src/test/invalid_with_token_auth.rs b/src/test/invalid_with_token_auth.rs index 75ed953..3b87aa0 100644 --- a/src/test/invalid_with_token_auth.rs +++ b/src/test/invalid_with_token_auth.rs @@ -3,7 +3,7 @@ use tokio::task; use crate::tcp_relay_client::client_config::ClientConfig; use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; const INVALID_TOKEN: &str = "AnInvalidTOKEN"; @@ -45,8 +45,8 @@ async fn invalid_with_token_auth() { // Start client relay crate::tcp_relay_client::run_app(ClientConfig { token: Some(INVALID_TOKEN.to_string()), - relay_url: format!("http://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("http://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() }) diff --git a/src/test/mod.rs b/src/test/mod.rs index 9135a92..c0f132d 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -9,15 +9,20 @@ enum PortsAllocation { ClientTryTLSWhileThereIsNoTLS, ValidTokenWithCustomIncrement, ValidWithTokenAuthMultiplePorts, + ValidWithTokenAuthAndServerTLS, + WithTokenAuthAndInvalidServerTLSBadCA, + WithTokenAuthAndInvalidServerTLSExpiredAndBadCN, } fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { 2100 + 20 * (alloc as u16) + index } -const LOCALHOST: &str = "127.0.0.1"; +const LOCALHOST_IP: &str = "127.0.0.1"; mod dummy_tcp_sockets; +mod pki; +mod test_files_utils; mod client_try_tls_while_there_is_no_tls; mod invalid_token_file; @@ -25,5 +30,8 @@ mod invalid_with_token_auth; mod valid_token_with_custom_increment; mod valid_with_multiple_token_auth; mod valid_with_token_auth; +mod valid_with_token_auth_and_server_tls; mod valid_with_token_auth_multiple_ports; mod valid_with_token_file; +mod with_token_auth_and_invalid_server_tls_bad_ca; +mod with_token_auth_and_invalid_server_tls_expired_and_bad_cn; diff --git a/src/test/pki.rs b/src/test/pki.rs new file mode 100644 index 0000000..cd0bfa7 --- /dev/null +++ b/src/test/pki.rs @@ -0,0 +1,53 @@ +use mktemp::Temp; + +use crate::test::test_files_utils::create_temp_file_with_content; + +pub struct PemHolder(Temp); + +impl PemHolder { + fn new(b: &[u8]) -> Self { + Self(create_temp_file_with_content(b)) + } + + pub fn file_path(&self) -> String { + self.0.to_str().unwrap().to_string() + } +} + +pub struct Pki { + pub expired_client_key: PemHolder, + pub expired_client_crt: PemHolder, + pub localhost_crt: PemHolder, + pub localhost_key: PemHolder, + pub other_ca_crl: PemHolder, + pub other_ca_crt: PemHolder, + pub other_ca_key: PemHolder, + pub revoked_client_crt: PemHolder, + pub revoked_client_key: PemHolder, + pub root_ca_crl: PemHolder, + pub root_ca_crt: PemHolder, + pub root_ca_key: PemHolder, + pub valid_client_crt: PemHolder, + pub valid_client_key: PemHolder, +} + +impl Pki { + pub fn load() -> Self { + Self { + expired_client_key: PemHolder::new(include_bytes!("test_pki/ExpiredClient.key")), + expired_client_crt: PemHolder::new(include_bytes!("test_pki/ExpiredClient.crt")), + localhost_crt: PemHolder::new(include_bytes!("test_pki/localhost.crt")), + localhost_key: PemHolder::new(include_bytes!("test_pki/localhost.key")), + other_ca_crl: PemHolder::new(include_bytes!("test_pki/OtherCA.crl")), + other_ca_crt: PemHolder::new(include_bytes!("test_pki/OtherCA.crt")), + other_ca_key: PemHolder::new(include_bytes!("test_pki/OtherCA.key")), + revoked_client_crt: PemHolder::new(include_bytes!("test_pki/RevokedClient.crt")), + revoked_client_key: PemHolder::new(include_bytes!("test_pki/RevokedClient.key")), + root_ca_crl: PemHolder::new(include_bytes!("test_pki/TCPTunnelTestCA.crl")), + root_ca_crt: PemHolder::new(include_bytes!("test_pki/TCPTunnelTestCA.crt")), + root_ca_key: PemHolder::new(include_bytes!("test_pki/TCPTunnelTestCA.key")), + valid_client_crt: PemHolder::new(include_bytes!("test_pki/ValidClient.crt")), + valid_client_key: PemHolder::new(include_bytes!("test_pki/ValidClient.key")), + } + } +} diff --git a/src/test/test_files_utils.rs b/src/test/test_files_utils.rs new file mode 100644 index 0000000..e7d305d --- /dev/null +++ b/src/test/test_files_utils.rs @@ -0,0 +1,7 @@ +use mktemp::Temp; + +pub fn create_temp_file_with_content(content: &[u8]) -> Temp { + let temp = Temp::new_file().unwrap(); + std::fs::write(&temp, content).unwrap(); + temp +} diff --git a/src/test/test_pki/ExpiredClient.crt b/src/test/test_pki/ExpiredClient.crt new file mode 100644 index 0000000..beb54f6 --- /dev/null +++ b/src/test/test_pki/ExpiredClient.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIELjCCAhagAwIBAgIRAOFWCcZCmPv3QHk6MwXfRogwDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAxMPVENQVHVubmVsVGVzdENBMB4XDTIyMDkwMjA3MDkxM1oXDTIy +MDkwMjA4MDkxM1owGDEWMBQGA1UEAxMNRXhwaXJlZENsaWVudDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANDTInGsDJ4xq/pSnpeTDSE6B2Z//Had0WQk +Wl6z4k6W5t79xFwjmMa4cfJJijfgC1usbV2+BP0nh+dPxedTlItUhIW8Hjx2BM/r +q1OPvYNu0bB7zcmT+WHddDLdfsxjSMt53b4UMbcWscflLry7V6ahoXccnPKUyt4U ++ZcYaoyPAej32y5Ym8EB2Hv9lMoRVbF02mEoTcdanJdhP/y28NNm9ezMsiv1jtCq +aR1ipVj7XdCW3K+vVLWzdfw75+P9bS5uXcAZHVQsJk37nrtezH/6Zgum9OQYUmIx +TNzhEzZiKfUWa07l0l3SC81KVf1YVKfwO8pQKATLLaauqXIQWZ8CAwEAAaNxMG8w +DgYDVR0PAQH/BAQDAgO4MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAd +BgNVHQ4EFgQUa/z5ULTQT52kxALqprqNhjhIcLswHwYDVR0jBBgwFoAU+53PiQbh +7KSQGc797M71fZg+JDUwDQYJKoZIhvcNAQELBQADggIBAF77OAeuaaW00zZfOuRb +9Eq6/MzS2kEUczFxkg6TZ3/cvx2tj9EQc7O5lRshbPmzjhGkRRLFBvnbL+wJrt93 +YS0enQNSGkdivS/q66Vqf0ujL/FhAxZYW5Gc+f7lLt0VYHzp/ChU2ryYx9dH2AJD +AKl9vSqz/e5rUyQm/8lU1gNWbf7zb8rHA5WcHGWzTJGdz/pnUx1Mf29dtcAygzwz +8yWJI1Rb755tGzocSPULvVuQw4Pvnum0fLJusLLBU9BTZzCW2psXUOaTzjwzza5C +WedEPB+/Rtw4cwydEwoI0OvoDXezKcjo8bj8Dna4+UqBz85PFQFZKT23gYBuz4/A +8/G/3pvXKf8DTnIo9370qU9Ce0UlohCu0U3rRQDEiMiTxQgkhHn7CXe0quOem9yt +RUOXymAUz/IdB/Xu0jfuZUF4e6ObF9yULb1SzmHmsxUD7i2h+453KmsYpSDWp2CP +R9UOrhINirSOr1qRm5PCnMO8b+Th7TlhfQBY3u8VTn1l5F4fdzGiIGV5IZmGb1fV +b47WC7y3TdJ6i5fWVt2XtKQBQOjOLgPfZs5qW8GFHWrW1Z2otn6vrNMgquhV/9kd +9TzSFgbymCFKvGkHXZQ70Rqkb8Q5v3dz3VSFfqdE728hvp3GRHqZDSJhcR/FVahm +AKio0jBH1mENEttHndQhXQkE +-----END CERTIFICATE----- diff --git a/src/test/test_pki/ExpiredClient.key b/src/test/test_pki/ExpiredClient.key new file mode 100644 index 0000000..187fcbc --- /dev/null +++ b/src/test/test_pki/ExpiredClient.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0NMicawMnjGr+lKel5MNIToHZn/8dp3RZCRaXrPiTpbm3v3E +XCOYxrhx8kmKN+ALW6xtXb4E/SeH50/F51OUi1SEhbwePHYEz+urU4+9g27RsHvN +yZP5Yd10Mt1+zGNIy3ndvhQxtxaxx+UuvLtXpqGhdxyc8pTK3hT5lxhqjI8B6Pfb +LlibwQHYe/2UyhFVsXTaYShNx1qcl2E//Lbw02b17MyyK/WO0KppHWKlWPtd0Jbc +r69UtbN1/Dvn4/1tLm5dwBkdVCwmTfueu17Mf/pmC6b05BhSYjFM3OETNmIp9RZr +TuXSXdILzUpV/VhUp/A7ylAoBMstpq6pchBZnwIDAQABAoIBACq3Zc5W4WXix0k3 +aVWcMQ1g726aM6yX7+NKRGom5d4ppCRtSKOIbJIJ3NUxEeMII4qnJOAOJLscQQKi +INuHD1XI/irVJmI7yhQ2Ix++wYeHPcGaMahQaq0IPeLByFRK4vMshJ2DSAAp1kgL +q5nTwMRHP947ric5JJ51L/Emf3Us1SBXBPppOJjy0yMTYpxGImKv/kelfFg5nHBT +rnhJ2CuyX0H9R/7Quigwif0Ul7Vth6lUlBm5Y5Ouf9SFN6HvBwqp5J0dSRGejFbn +5P7UrKpAL4GR+zocYXi4iv+5ffOj7LKPm47pym5WUJgo04HH+CbajO4R3XFpOyP/ +I7cj2uECgYEA5SYMAJDGLepkkSbyWd8pvxrHBYlbEFNXmjPaYdCQUTfLqffFl2wb +saa/WxW9vQwMKLl0oLRtrEoey2ma3Wx65RLBRke4+WDo/6KRe7jA/C6MjbBTutAn +hducVPkw4hKV/ERPb07cGGBA+N3VkS/BaxMu4Ki8oGfOyo53FJ6gvzcCgYEA6Utq +jKN86GSL3Iy3tebhWbHw1vNN6JitQYVmlJ2THiVuQBKT9NK0OfPTQgQoWUWKK0v8 +lodQ1VoC0iiDGHYVjTtRwCT3ajS6/3T8mrpTWWi/gQRB6SXIoQrXC6rs/+OPrRbb +uGP/nkLBj1EzPOeldv1jN5nTxxoW634RxuPd3NkCgYEA5Lm9cTMRHfPAvkIp1hsz +CFYqIhSgmQMXhgwMB2avJuKSn+15hVObsQ/IIZrp8TF9UYkMKPzwG/FAG7oloq8N +XGoEEaq1r/ZTnBchMGWR/CZalXNToDz1tl8nBIpXiNEUdOGaiHgmqQ4qzD5hVrJc +Vgyn1geXgGUdvIHHywUrXrECgYEAzrI77+k11Oyoojqm1ep+hKrMOJYO0+LZtnCM +B2ZpH0+IlAohvsskVSg7Z4UpfpbHKT9ExtWS/8SlNTAhnn2Y8K2666OU9itL9uPe +nvQwvsm4yoVMJFaOoGhrSXIiU0F6XaAgAgnPQ5ffyKvn2rFef8NWsb9/zCrIXdMv +yui+/FkCgYB9y+OJQ/CrkHC5zQqsG6PnKw7GZOII0fOrWdCUAJwCG0dv7cZJ03LQ +yONxAVdrzTGGOZTOD2vG0oG3XDie2O75qU8d/OUcdl7OqnIqupGUZMARnW0Xny6U +fpFdGYs8KeohUfw8LSf95VwJwSBb3zjaPPTR/ZZ+LI3k8wStXlOMiQ== +-----END RSA PRIVATE KEY----- diff --git a/src/test/test_pki/OtherCA.crl b/src/test/test_pki/OtherCA.crl new file mode 100644 index 0000000..497387b --- /dev/null +++ b/src/test/test_pki/OtherCA.crl @@ -0,0 +1,16 @@ +-----BEGIN X509 CRL----- +MIICgTBrAgEBMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMTB090aGVyQ0EXDTIy +MDkwMjA3MTI0MloXDTQyMDkwMjA3MTI0MFowAKAjMCEwHwYDVR0jBBgwFoAUIdv7 +GAAmusKCN710x76ODIzpFDswDQYJKoZIhvcNAQELBQADggIBAJ6PEWN9ZdK6V1Z+ +qb1lE6UpDwee7Gvu+WmYLc/ySDy8zpt3er5bfJFEI5zLYRvR7C8I77QuHfm6ytny +AcjdZoqLoYn6JkEnbZFj9yddcYfwmo1bxc7YsGKqitQPwUA+Ou2mq9q8pSyAIAY3 +d1cAKEqHZgnWm/7D4NZZ8lWGjjFz9hlwhP8jWKqRcGsL/RGylNW9wyroECGRg18R +YiFIqgXiWAG1CAZcbcv2yKlijSm2q8OgBG5mFMClm5yHEmyju4ZyRowySraSkMkc +1lZqOpxRFn59FNE278bm4RJfWFtprvO/1UONq46VIi49q3iykjowGS9enFhd2pDX +JGRiMze5+Y9+MRqB7CkpgWr85a6VB/eZHt1klZDXHVviTPBwf7Sps0u2j63ZgMKl +NZCG4oTyPguyNF+PF76xqwhGqJJB1zK63wizC+1go4It9vn22tg3/C2X1riWiKjN +XimlHyumq1DkRoulwo716m3/DgVbAQD+dfTmGA80QnCMAEpRG0rjBwwrsbuz7TSX +38YiBCBAbgM/L/XhVXzuki0Q5xrrcvH8bhxG6/j+gpAFdI3on2R3rHgWMXS8c9tw +4gqXuPr4Th3Rb3pwZEsWvUXG3vY/5d2Pq9gCGcEUo36CCaZzMCDh7yrJHd1zY5gT +e5zdMjCWD7b5jfM0GpSthrfh7cya +-----END X509 CRL----- diff --git a/src/test/test_pki/OtherCA.crt b/src/test/test_pki/OtherCA.crt new file mode 100644 index 0000000..f2221c9 --- /dev/null +++ b/src/test/test_pki/OtherCA.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE5DCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwdPdGhl +ckNBMB4XDTIyMDkwMjA3MTI0MloXDTQyMDkwMjA3MTI0MFowEjEQMA4GA1UEAxMH +T3RoZXJDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM802FZEmSvZ +A+SfJNWBJsAt7SvWQBxxpzmP8joriDkULG4XCiJGAHY7MsNm6uAk/A2f3TNEghiL +tbfQtJKfOEC2NDe8Y9H7bKo9cVep2YORGuXuDH4dkX4oAYYgKbdYSeMHyOsOkpEG +1FBlA4rw73RuO/aMqF25e1idLWXgi5fk8SUiWgH9Twse8KcYg8v3pA/SZcoZtc2S +rSsJFZJCrEOPZMJpTilW3Sd6KlZ+1niOAyEksYEy+ACQs9PU1H6edn6S+oNxpF24 +iy3Orr4u3miU40SDOtO2qtrv/6vlbXZaIju5KyEZSMyve0Vvc4v02xUfdGxNPR2y +r7IDd0lIfewLMohpE2m2g2VPkWvC+EMkW3lA/a5xyDotF6aFGKblABRjHIRwNORT +tx7/jXoX5Cg9zGmLrs3/MhNJvGsErfnNCmDvlP7J7+JbpFgDMJo1uOv1ozLu344Y +R75trQBaOglTNNNs0D2sIgfEJTdwOt4PvGMgClcYGerjRZEKFmiX6//S6JBnlfGp +d5cWDgLv67sHKk9FXbbsZpomoGOqWKF5DuPoUH+0yOEq4LSoqMmaxFIVf3LgIvD5 +G+1xV5jxkJsWv9JSY6QpYS9JDSpaOe2FqsQGF8VCd2SOnlzGxnMAISpT9xHrtYu+ +fCXnf+gXWUsy5Y01It7CMHnW6cFhP+ATAgMBAAGjRTBDMA4GA1UdDwEB/wQEAwIB +BjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQh2/sYACa6woI3vXTHvo4M +jOkUOzANBgkqhkiG9w0BAQsFAAOCAgEAHLGe4p4gBwn2vCotnFxNRc/4NKkRkvO7 +dlr2jKGCIFfGgU9JsgaYYUckxDzkQadOujpuqeuB4J9OfH+GmbUNG8MOuSJdhtKi +sASnYoaF17Go7cOg/6k0GfN5FuIQPjEOM8yFGhAhP4MfsWlNWxUQPh/3QewjfEUt +TNJXZ/1zyY2Bjt5hygdSJ8eDe7V8fVV+HcLj17bfgfP+ILbgxPhsc0Sqh719j0va +gptqzrLz1eSKjthwVrYh3RuJCBPJJKa51y54TKIqnDkrWEQc0YQf7K3wkJJQ7H6M +UELhZLVF2zjEltxcfDGUCHtxcWYApA6chwsDTNYoeb7KdTAmXgQS7JNTqLuvF773 +nGCKQr6JYPwnQ7QOE7oWVEeINGZtSyKBb/+DpTacK0qaw7MymkJBlaRNHAGsTzfI +U0/tKLsi6ItXi8vY/wTxRt4qvlu4mFeGFoTNdTDib6rJKS4D6HoGeRglhefOpv4r +luaJ3MwANCTa0T5H/+vDN1NQTMJa6Iul6gKzDkX1vB1duenPpExAgnjm3QeNCvQ/ +yqNCPEAyZBg83L6ZKCEHQWo3SM2nMwV6X+pS0FKCY/z+7EGH6A4FHriaksOnSNeD +HczdA3Kp8jCR9llFknwxvwvIzFbh73E0/KVifIfzmbKakIseohKRNF1kxhFaB+wR +DE1o4VTfHl8= +-----END CERTIFICATE----- diff --git a/src/test/test_pki/OtherCA.key b/src/test/test_pki/OtherCA.key new file mode 100644 index 0000000..6948213 --- /dev/null +++ b/src/test/test_pki/OtherCA.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKgIBAAKCAgEAzzTYVkSZK9kD5J8k1YEmwC3tK9ZAHHGnOY/yOiuIORQsbhcK +IkYAdjsyw2bq4CT8DZ/dM0SCGIu1t9C0kp84QLY0N7xj0ftsqj1xV6nZg5Ea5e4M +fh2RfigBhiApt1hJ4wfI6w6SkQbUUGUDivDvdG479oyoXbl7WJ0tZeCLl+TxJSJa +Af1PCx7wpxiDy/ekD9Jlyhm1zZKtKwkVkkKsQ49kwmlOKVbdJ3oqVn7WeI4DISSx +gTL4AJCz09TUfp52fpL6g3GkXbiLLc6uvi7eaJTjRIM607aq2u//q+VtdloiO7kr +IRlIzK97RW9zi/TbFR90bE09HbKvsgN3SUh97AsyiGkTabaDZU+Ra8L4QyRbeUD9 +rnHIOi0XpoUYpuUAFGMchHA05FO3Hv+NehfkKD3MaYuuzf8yE0m8awSt+c0KYO+U +/snv4lukWAMwmjW46/WjMu7fjhhHvm2tAFo6CVM002zQPawiB8QlN3A63g+8YyAK +VxgZ6uNFkQoWaJfr/9LokGeV8al3lxYOAu/ruwcqT0VdtuxmmiagY6pYoXkO4+hQ +f7TI4SrgtKioyZrEUhV/cuAi8Pkb7XFXmPGQmxa/0lJjpClhL0kNKlo57YWqxAYX +xUJ3ZI6eXMbGcwAhKlP3Eeu1i758Jed/6BdZSzLljTUi3sIwedbpwWE/4BMCAwEA +AQKCAgBpNGCfNIc8vxv96VuvV7rQGsFv34F/r6kDTfXj2RR6PqbsYqBPlJFJdnco +xUl98ulTFZcfH6qaQd1K7hmw1EygdqJ+phVcmTasHTQ+GUwKRBOPKNWI9wRXNILJ +kez8XURulBZMWoLKRdho1VD+K6S4zft+DB60L6fT70IMlvzpa2GQxCdFGVMXx2bS +wFyypBLVwbLS8UjgjpeD4UHlmBqU1uqG1ybLUIJLN/jlH9NPNHOcUWAaxEEtMEtN +w6L8gwKQ85lkQb/9oeRwpp8Miwl7uhTGRYcJ1ZZcQTzkD0ILtGnrPvIKBSd0XajO +MW9OYU0XJXhcQL9GI+KXFLFtMPRViMY8CrVY88tG4MhvI8q/Yfg4An7ly1fd/PPy +5eZHRGwCOPN8psqmkCZaGPwnADy+vfoUJUa0CUffZ/KlS7PWykcVsJclwkcBWYUo +rZtbxtoAJtKIMYCCL/PndyQLRZPaOL7DuSFYq3kcj7F019N7d8jLBBtGAdXgVs1U +GcRH2JVjMfdWmbpria2Y9PjFNL3KXUQOIgQE/Y9tIlGnfEtefYTI32t4/QIdAVCA +c+olxlZz9+elrj3Z58Z4QAgfUdaljIMwiZD5EQMGC/jiOZyv/5mxHmIlrFvUdVDd +6K/1YmMBJjNnBbca92pkXSGWyKe7sJoehx2kaGGiX71+KPSjmQKCAQEA0SICiNHL +MJoMHQZhfY64wz6HF9s9vUChH8bD0rkLmWFA467e0gfhr7U62Gwsg9A8sJOq88vA +8LokprRvE89Q8hWgzGiN6Xh2myIErs+VipWS5kQW7f7qsp2ysScKnxQTZf/Gj5Mf +6qTXuAOGAjrGd7Fk+m1uQ7R/ZBVJSfPQaLdM0o+o+Vy2ddgxqz5Ytrhq8x86Fi4N +Zs3sU23PSMP/C5ZDaXraMEnn3X6rxbJYzJYWvK20nPCYfV6n6Gcavf1ca1iMYY2y +19iKKZwTVDesZCJ3zpHonm+Lbjjx4/OLUx4RVRR37FfpK7AoKSdMQ4k92jsscAD+ +SBqh1Ohgb34hjwKCAQEA/aRQ2Gvf1PHYM18iVaV2rbZWn8axh0l6cOx4umlqHQbU +Qn2ZOrB3Povw2ieySGogI3vsQkxdSrGQ+l3y88bgE/0ZI0xGFxeGViiOgHhNq5Ac +QJTTNSYwh7j10zkHnwsI+ow8lmt8fKBikG2jinLCz1V3julAOAj9QnluM6RRIuT/ +JA5law+3HKA25+a8e9lUSUNxJsSzLi4YmsKMhNNSjhD4SquTV4bj6znQqNd0Kehz +Ix80Rfw8g0arQwDDDuqEN5xxPdAFgZoR/ECcpb29SygMBaTlmYhsN31L2qGevzBS +yZCx+iYLZoqRUr7m0kcZH1nHwMDhn3+RuaRF7d2PPQKCAQEAjh01abJfCIT2TFcE +suTkq1D3Tn/ewZeEpmpUsgKrXixXgyFXK5TNibB275D64wwD4d5HImrIjw1/UIV2 +ohiUoh2Oarl2DjydJKiGVCCeN1GTRMTqbAp5hK1jO70TG6zxzbN1RCWvX61rJhHG +5Ab6zWWQABmS/5FNrD5G0mlLq408OC4FnoahOw2SGxNAB9LkYphKyb27v6uZt8v8 +Oy9tRntzDd+9G2ltlfe5VJvwef5YLxk/jhJ1HWTQZz6BTrA4OH4wzy4SZVkx8jqs +a+N1U4qUrZw7XkbgkiNCRSw/9liNYKqLH+FRgy2u7OBWk+JUVNM3TFlwcqEebecH +eVxWAwKCAQEAuD3EcACj/XWTO3WuZhIkC/j4IWVeDUyFgUN0SsxJxT3xrz62sFgA +tlFGqeDN8yYLpFre+iWoWppzGjpmQUfD+yENQoOkIh/3d9xL7uv0V1v9+bdhWCke +dWgYQM8bRx7n7b8yP31iVtDV592MPwQvmBWYHBo4iLuW49N7Bk4klblLz/AZIVSw +CT4jw/3qCfiK7hDsP2IAWdooCzqogc9TF1kiUnMhOyIDqxk7BXpDqjFseSWwfenE +NwN9YdVK2ynk0tRzuZfCeCrnR5nTb91MhCxZ1zu5f/YFzaTZFb3ypyQ97qaJcZBz +FZAwEbAT0MjOaeR4Yf55pbcvrm6yUR9wbQKCAQEAlwyZt/V8JM5g7vlxpvugKzpy +J7fdMY72fAWwWukSfJRkssx1LYGryzeFppEhJvoLQtAzDNHJNM4tQ0pIfb1xf0Oq +qk8hzN5d0R2ck/KqAYj4yli+Ik6upUCuiyR76CsnDd24ninZBWsro+iXAz+taF0g +0c+Rk/kxqL+k9InAAhU5Z8mxk/uKH1SnuSYnJzKtPbcex7l8I/7oBohXHsq7CcPJ +I76Hc7eiaF06MBfaxr/lJVJydo0wj0d19dKchfu6p6RgddMpPKTSVzd1T9bKY+i6 +nHaV5mRmrjqtGN7Z/MntpjjQdDPdKv0uMtG0yfNguVbDgu1q2+7lJoIWJX8/bw== +-----END RSA PRIVATE KEY----- diff --git a/src/test/test_pki/RevokedClient.crt b/src/test/test_pki/RevokedClient.crt new file mode 100644 index 0000000..27a9189 --- /dev/null +++ b/src/test/test_pki/RevokedClient.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIELjCCAhagAwIBAgIRAMvrVtV8eUCAihX59TzwyVwwDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAxMPVENQVHVubmVsVGVzdENBMB4XDTIyMDkwMjA3MDcwN1oXDTQy +MDkwMjA3MDYxMlowGDEWMBQGA1UEAxMNUmV2b2tlZENsaWVudDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAOJ0s0ukj6FaKVQW1rZ7fdT7CqFyBcbQ0yr9 +nioaFIICJIiN/RsTROlwEtFBYoy68SP/9w+p4c0T+1QXr2T7JBljZ8I0RotPmUL9 +Jy6fM5dD8m4GM44K4oz+Mk6JaVNOcY1+j670KLRJKLhX/gNTiiqFdmMXrLUdl2KF +3qrY2Jh4riygkO0xClKiL57m/8+tCDXI+cycftdfLMDOLkBPA7HCeVdahx2r6mHi +5tSlk+sMeXEJy7kR4w4zDUb/MwP1cQgnSMwtdGE4Xz2zSLwEk0P8xNUe7Qwwx605 +syd/Y/lFDasoPeGgCqFvw/zgZE2D+6U8NbywZBAqa/Nd+UA0v+cCAwEAAaNxMG8w +DgYDVR0PAQH/BAQDAgO4MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAd +BgNVHQ4EFgQUOJMPHK9liHjNrIt26DT1pWmat4EwHwYDVR0jBBgwFoAU+53PiQbh +7KSQGc797M71fZg+JDUwDQYJKoZIhvcNAQELBQADggIBAI7d1CIJGwwTATNv1ATl +UawbtuuV2dbasRA3C9kkG34UOmE8m9z01/rJiwXvF+57rbPMTZUvVhqOGajJNN7K +7+S1DDUNjea7snbJO4zsHT6OGV1vw/b0EI4OJKxuYRE5kkUEGPcWSoFbsUEyEXtt +Kl22TDOXCEYkvYW5vN2aJokyPl+rmCrzC6E207lkaKyDDBSBPYXxNApBkMMryxUO +1yqRxYrfayb0CW0JRHzI9dQNOPtpj3Pd8XKxC0liguTnPReoHC1scTp6GR9uP5TT +MlBPuAudcRNd4Kcz4vqBNc3M+ioWt5DBQ4n31beq772AbESpDaM5VBRdDlre6/Q3 +WEasplODNer44md+V09LbhT3sDYpHuTIYwvHcf7jOO6wUKl7JulOwEkBD2IiTs+6 +RMT2eIavlQjIObqNvLTWoVfm4b32vvBzyXdrZyr1FIlJ+VlhIpvEC1ZPq3ZLC831 +sDPtyVI+dA4KV/+ZN3NvP0BfL9+7KE20Ma1V2u8reV51nddjRzNkYt3AdAuO3B9i +CUqauhe5o7Ey7QFRAxYvT4xmg9mRjSJSlX+jwXroKymtxgG3f/14Do+5yyN0bS3O +FC1H3uV1vwQztxkpJdh8PoWoh+1OsqwrRIYSEAx9M1xSBHz5TzgHQJmot5fwLQTn +QgvMyCyS46ciaMjRILqagt6P +-----END CERTIFICATE----- diff --git a/src/test/test_pki/RevokedClient.key b/src/test/test_pki/RevokedClient.key new file mode 100644 index 0000000..126ea2e --- /dev/null +++ b/src/test/test_pki/RevokedClient.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA4nSzS6SPoVopVBbWtnt91PsKoXIFxtDTKv2eKhoUggIkiI39 +GxNE6XAS0UFijLrxI//3D6nhzRP7VBevZPskGWNnwjRGi0+ZQv0nLp8zl0PybgYz +jgrijP4yTolpU05xjX6PrvQotEkouFf+A1OKKoV2YxestR2XYoXeqtjYmHiuLKCQ +7TEKUqIvnub/z60INcj5zJx+118swM4uQE8DscJ5V1qHHavqYeLm1KWT6wx5cQnL +uRHjDjMNRv8zA/VxCCdIzC10YThfPbNIvASTQ/zE1R7tDDDHrTmzJ39j+UUNqyg9 +4aAKoW/D/OBkTYP7pTw1vLBkECpr8135QDS/5wIDAQABAoIBAEtCJWP6KJGi+SEt +BeZXXBYv5/SHhEvyknszFiE/0ZjzRVjsdzVMThaWXGqWpD3I0uL36g+Wkagp/9iO +loekvvaBBraP0PHzXifZIfBokCixOBxAi1mlXG0m/WkEWbCJ3Ur8yJuIIQ7pUVMS +SySn2r8O461C7O60Ct9/ReTZdAIXWRj8uKiJF731RMZ/NFaOZfom5ijFyKcspyQ0 +ap6CCpx8cZ3M8IUwHZJFgoET8tJX+6LftYKTKhE2LjBBzmGw1xFDuOEXmkrb62Fd +1HHUOdkgT3+2SLR3Mz8piWdhhvlg57+WTIKsA5Kx9GTDjIUUTXK5s3PsgxObEpc2 +JWLhuaECgYEA695jleVohwX1z/I3idmZpSJK1MJOi09Pj4IvR+RXtKN5DpGhQGRO +x5TLGxJ9F2nQMErW8+oVBotl39iaFAlT77+CShBtBS7JfDX76whAvLwnouy8Winz +YV9IBOFl9XT4hVhvkR7BAzm5CsKAiT9OJRPxX0uHdmsWbnTjMwcG0csCgYEA9cil +Pes5ZOQ9Yn+M9wufrOJZ5FnC9NYvgre89OZTQhjISZmX0iW6McVkqEc7Av1S4IGC +t8+jVgq4f2XWle83GYrnWxwItGADJdL/X2YWWqzzEvTeyLs3zuLtZUt4wG5MDJJ/ +XJaTiuA+a9r6/fsQto+0LI43R6Ge5UERi91qVtUCgYABvQLY4PbzP8z++lcEchEa +0XThuojfp/b7JMd6bSlkUGwc+l/I3LRj7inNCkbXvFTndjW9WHVNNgvLKYqBKUxw +EOZB63sSNbUQcElqAwaPHYfhQINm2rZLemtKderNc049lVhFJoffoTZG6QYPfOLz +jQETZbga3FEvATeHcb7QHwKBgH0DPzkNSbYNeUN+SP7nBKJ0xvAkz8qknqnINu4B +sNtvq3/0BYq38cqa8iW9hUByBRN4DDrd++Apt8nkzI6ai9YMFrz6t1q3cyJr/cRS +MpCQY1qC/kXvI+Ww+rqI9rQ55aiHYwx+8jCy+kz1prBEYS3aTfRTqb5fcGh+/iO7 +zPi5AoGBANvsVAjy0HJxJom8yfCPw2tzMPh7o9v1jMblKN1xX8B249i27S5UOifO +Viy0OR6uiNGT6YLA7Q7esGavkiuK0bWa0M9ezWbGoNh4DmOzn9Q8yEbDz9VF23Pw +fc52Ehiq9zS9cqIXc+cQJe/o2J6YziUnBcJc2Ld7d75TISkkdYrN +-----END RSA PRIVATE KEY----- diff --git a/src/test/test_pki/TCPTunnelTestCA.crl b/src/test/test_pki/TCPTunnelTestCA.crl new file mode 100644 index 0000000..d72bf3a --- /dev/null +++ b/src/test/test_pki/TCPTunnelTestCA.crl @@ -0,0 +1,17 @@ +-----BEGIN X509 CRL----- +MIICrjCBlwIBATANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9UQ1BUdW5uZWxU +ZXN0Q0EXDTIyMDkwMjA3MDgwNFoXDTIyMDkwMjA3MDgwNFowJDAiAhEAy+tW1Xx5 +QICKFfn1PPDJXBcNMjIwOTAyMDcwODA0WqAjMCEwHwYDVR0jBBgwFoAU+53PiQbh +7KSQGc797M71fZg+JDUwDQYJKoZIhvcNAQELBQADggIBAAT08Q5BJIU+yvPSsNdE +yMBQZSUfTyFOxWYeUiqohpRkCBdhWYAnrZiZN83GArW7rFi1D9p0Cdg5ayDgY1A3 +4SsnXklwcEdYxIzaLskN1bRY7Idmu9TXdDssPWCyawTfWfV5AfqnqnuKx71gradf +jMixrOoOWiBqMp3kHO6F2Q5gKGTQcvjYAe9yVeOF/tchMiHEHBw59HigiHmkX4od +7GNbyWyqJlMaVoK13hOt/qnjOFKITsUSzIZ1pI8NY44sBFSIM1SzklfZZ3vBNaeC +gA6JBrBm/vEvbZ/WsfCI0uVJwLgCoY4tupocKCLwyN2tyGFhvPwlv4UFEEkabYuo +9F7/5CG3JO2yJPHMuflebLawyyfXlbjH9fqvjNRnyry3MXsdphU5OV/xavrSNgLW +i8HItaFThCvnMdlMn38UYeGUqp/lgrpQiXEA8K+BX55lJzzNK+UPLNEkf3bROWvR +01tstOAhn0rfPKW01HjqXKU8Si2ExBR+kzdamhiZoaKcxuemK/TPd+vmNXuvwede +3o2qdXycgFddbKmKejV3gy+zptnFyEGlC3E3BgfSdQ2Tdn0BBltzhRdENB6o5SYh +ZUP4Mo3Gr0Hy7eeLGQM7wzmxUxOGmVdqDoWnbOwC2ySEzR6Tsf9id7Sl50DDUcS5 +G20W0UM0cWIOyaaHAxKl9frl +-----END X509 CRL----- diff --git a/src/test/test_pki/TCPTunnelTestCA.crt b/src/test/test_pki/TCPTunnelTestCA.crt new file mode 100644 index 0000000..7a67b36 --- /dev/null +++ b/src/test/test_pki/TCPTunnelTestCA.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE9DCCAtygAwIBAgIBATANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9UQ1BU +dW5uZWxUZXN0Q0EwHhcNMjIwOTAyMDcwNjE0WhcNNDIwOTAyMDcwNjEzWjAaMRgw +FgYDVQQDEw9UQ1BUdW5uZWxUZXN0Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQC5agi1SIe/1SqoBb+p3IstdnZa12IrKtTiSSANV/RtjLgFymqqlvNd +I3OJOglJr/ISSWrldh+ZRb661Ds7USLPYC+ZGUXK4jRoe+CvW+WjqUMKbZu2CrAO +YmlSy09QCARJX1kv1dLDgukfOmXCTz65uMpf6hZzTr/KNCWJImXSfsJLsuUqhRLn +M4mEV3P2TX6hrtAYa8vCVqRO4vlFOvmYdYIOT/TfLTMhmqqodVFQMoUFvl4/ZZEc +dEmJOInd+yktSCO9Ziv+A/24Zb9mY46X80NVSoUmvTYB2FEo3AMqmxq1QHo3I7/k +3NxK2uLE3xFkpXckHI+FfTjuNvYBn+EqR0FNuCiM+YsCapYBZOW2olMHZs3BI+A3 +nFS4JGWN53qno5GqKl0mm16b5jt+O7qy6997VvvKlkOgXOFGfa3L3x9lR/i4WUIS ++oK1M94xJtbhUgVSH1N8K6J52jyl1EEGCR/LbW2762Db0jIQXT2/T6k0HsF+CVVR +BLOMdV8V2JrcXCcnW6L0jGl1pXO9idgnlNlGCndjM6E2wvr6livg7Fjpxw+xJLA1 +BMhc8gaKxcVZBcHkdmK2G6q49GAO5s6DCiGuNpGgZ1YCAV6OflbKiIJWPV/sGOp9 +iLEnxYXTAaYMwM86yfBqkIpQk7dqWa5Qfwfb+o2vDhWY5e6/bHdhGwIDAQABo0Uw +QzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU ++53PiQbh7KSQGc797M71fZg+JDUwDQYJKoZIhvcNAQELBQADggIBAFIqak9dGO/i +mMRZGu9E7fItltodw9Qphixn5SKc1Rgf6RRj/XGj10JrYiG0ULnEsMLMCu9G4GAp +IM2LKYLcirOvP+bM1sWS4ieMrldCVlbJdnhz8TnWInHb1+CNTvXKt41rc/NGsDCp +QODmj2Iwd2/QI13ABKGSxjXUvTWl4Cq9kSUvkDZjV/WFjb8nUs6Y6vNQZTc3rne2 +CUb5+xDRmgz6q/SsAtgH8Rrzt8KYhrT5r4kMkpIFssLBWUQgHGdZEaEnt89qnIVb +/mULw7l0716yTkqUBydibyDUsvhgOh1c5Xg/8ICwVptvFzzcbvWFtMjOQCuqB/ud +lBcMPIlM2CyytQ6uJjcjEfoy2O1rAlgEb2QKR7abPinlLFo2d1kx3GwPgSzdpROB +fJalW0QDLkdeSPSX2a/99KTI8GKQKriG5D2kcHVFAY57P7yjbyrLtD2dKdCTp0M5 +jPMGjWvFOJ86k8XiNB8yMtABp0K5WZLqqvPFm16sBPaJnpKGo/KUipnLOTnEOpHJ +LWDDH8P+HKjhV99s7IwBu+67sDsKO/AsZGRuLJSGh1j8nl/iKhHGgXPfGPY7oDIZ +6JyqnW0906KrIoUFZ0b8iKMwIu35aVR++rfWIdFcYqW4flNkAZI0XY5IlJ/i9d7N +0ezY2xRAYlJSvefisMIylm0OgUDg0Nv7 +-----END CERTIFICATE----- diff --git a/src/test/test_pki/TCPTunnelTestCA.key b/src/test/test_pki/TCPTunnelTestCA.key new file mode 100644 index 0000000..7970a50 --- /dev/null +++ b/src/test/test_pki/TCPTunnelTestCA.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/src/test/test_pki/ValidClient.crt b/src/test/test_pki/ValidClient.crt new file mode 100644 index 0000000..ca62152 --- /dev/null +++ b/src/test/test_pki/ValidClient.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIELDCCAhSgAwIBAgIRAMBV0/1Yv1gtGnyi/NMvFl0wDQYJKoZIhvcNAQELBQAw +GjEYMBYGA1UEAxMPVENQVHVubmVsVGVzdENBMB4XDTIyMDkwMjA3MDczN1oXDTQy +MDkwMjA3MDYxMlowFjEUMBIGA1UEAxMLVmFsaWRDbGllbnQwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCd5PIwp/QUA3UVHDHLBQankyDTOyQxSzKR6CbO +yh2hkTs/l78eI2KewovYgP4oowRsHYUTNcZHBBKm3fE6BoZOVuQg0Tw126opJ5WE +O57nPoeqn/Rlic+lm8r/IM6rUCU0cuPrP3OgzGKgceldlnWmBZ6z6CPtClgv0H0E +gpvW57/gfveW4JfON4w+CjWKFFwAdk7NwgwAVupDeTDvzdK4ExWY/cGDs3NynAS/ +xS8C2KBVmK40l9eE0HMY6cFQ54hM9wYVeZFZsCQ+9P/3ywEtdb1xsVjcDzmk5Uhx +wVGrzu9FIowx1K3b/zINQVhefsDPCa/IfMy4NaNxwg65zqjZAgMBAAGjcTBvMA4G +A1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYD +VR0OBBYEFPw35WYKl2KasK9cNi2tROUQFX+RMB8GA1UdIwQYMBaAFPudz4kG4eyk +kBnO/ezO9X2YPiQ1MA0GCSqGSIb3DQEBCwUAA4ICAQAe33X1mHnOIWeCA7XZGBVu ++zbXTheHOSZICrM/pOzNbspTTFkQ68sBOwd2HcFhhm1WX09b05ipYiEbXNZCIELq +RWPN6yr7x7zFNjZyXxZAtL01pOVih8yfyg1WgW2hVB3VH9/9txMRIySfRoD8OMD9 +rJfE8mhJcCELY1Fp2G4U6pghoGqRTyalHO5pxVFQuumudYnNlJhdSflcL6Y17Y5F +pclI8vJ3j940x/w1XfAd68xiw/Rc6SZQzIzvl6mjSGyFX5Un814wWXQZ7kAtH9fV +d8l75O02GLoocmkePwPFmhqc09WYAZTZgxJqEPyI6S1VHOUBsGru5rkY44zeRs2p +V2jHSIpcsbP04iwMDNFJV24Fio8A9hV4LFm5Nyv3O6gBgyyiRnYGvfS9R6wazGNW +LXAXQw69Wios4PxdlIX85jIJgyJ5GrjpjTTYmzkhe7fs8s3jdm4a2mFMWQcjbSia +15mF/1TdVNcKqt/M55aYY6HL3AnIc90TDIXr7UWZVJSeYicVZdI8N0Ih/1myOYw7 +3NvqUetYLw/FQ7C+763N9QLgSdPlBTMkMSyB2pkXAAzWwJ/UPJ6z5REZmTVHu8Kf +I5UD0GwVnfUpBTLEpUG4oTH39PhKlncCKtmMnaZiu0DzxMy0xeskFT7YZFj0BKQc +JXXeqkcOvTFHibpLR5lQ1Q== +-----END CERTIFICATE----- diff --git a/src/test/test_pki/ValidClient.key b/src/test/test_pki/ValidClient.key new file mode 100644 index 0000000..c8ffe2e --- /dev/null +++ b/src/test/test_pki/ValidClient.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAneTyMKf0FAN1FRwxywUGp5Mg0zskMUsykegmzsodoZE7P5e/ +HiNinsKL2ID+KKMEbB2FEzXGRwQSpt3xOgaGTlbkINE8NduqKSeVhDue5z6Hqp/0 +ZYnPpZvK/yDOq1AlNHLj6z9zoMxioHHpXZZ1pgWes+gj7QpYL9B9BIKb1ue/4H73 +luCXzjeMPgo1ihRcAHZOzcIMAFbqQ3kw783SuBMVmP3Bg7NzcpwEv8UvAtigVZiu +NJfXhNBzGOnBUOeITPcGFXmRWbAkPvT/98sBLXW9cbFY3A85pOVIccFRq87vRSKM +MdSt2/8yDUFYXn7AzwmvyHzMuDWjccIOuc6o2QIDAQABAoIBAQCdaZfOzFK49S1v +61j090DIJhVOoaKWhkqXTiQKe1QJNJol7yo5aLu0XW5AXXGFn+gTxWZbXXwcZsIV +nCUXXVPenB/5W8A0TZgaSX11hF8KWbu1bpyf8kGS8Hvz2IhSIKfG31e8u9iSEdGt +9YLbq9oEt4ud/qx6cJq0qJ1Kts+Y8ofAXjTqxa0+LVmCPRJFp1CjCAanq/VBx+cR +TjDMcBAnKB8u1wrMc4Hw8ew693wHaxYQEm1bZkjplQbUCA/IKTr1otIyCHRpNKUJ +XmNTr+zU0zqjGudeeNrEu8vjXMFzlWXoKlbVoYgfJ7lIp/9s2KDa/AjEpsrbmDo6 +vAsH9gnFAoGBAMOcEd7LQFoIxdNl2BFV4jDoSLrTeNjTwXFfe4/UQSvb8lAwzYl5 +aD7uT6XpkK5PV0vX9w6Wi0JVidbZVRmF0Ml+sXn/SpV9juQxMR5GpCWsCz1H+3Vj +a11GyAy836tX5harxLWhQq/q7HEit7SnNTe5i5Hvin8v1S7jfo6hdQ3TAoGBAM6k +D3q8yBu/JDrruL1SfyKiQT+U+9ccR6OJ713qsM9gZ1HocbFMDwVXLG3U+NRRmhxF +xbY9zyEaLERcNAPbbm/aB+hXCsBAIe5XO5EIYGi5cP2+/2UjDxx/YIZkx71fe/5+ +QoVUc+TK1i9lCZUXEvDxnVZdMYsu6dOEHldxvwcjAoGBAMJ/1DERLrqXkIUj9lU+ +bXut7GuATOBkpitiAs3AAtFmkSl1bVot0x8H/UB+3rLEB4xNgMYLoQrjXPy5+2k2 +aqWACV7CHtpID6YM18c//IXM7RwREBLoOWB1OgOYZlrMOuf+AcmMQHAFivbvy3Sg +8kSnhQUmBzNyT2qhID0Yg/irAoGBAIDfAGhjY8kqI8Y7TDOGR5Op7Vdh6s307Rio +5YeE3k/2p3kFpiIUdSm3fBXjRGvlmF8ZhHxrf8n9MK5Rcn8VUoKfT18vKZ1MYdzq +ulNxDe9B953IiC7i9oGnTuOB5q/L5OCKjaHpUX3Wok1cjeVVRpLNnHpIFKXg1CL9 +uo5+ecxRAoGBAKUr4pYT8wmu8BoNNoVkn6/c7m7ssBJxRUsj7cjxNpCIXzUKMzDj +Vqup7ex/tVOXZ10JEE96IMvm+b+Dje32x5oP2qaMYAlAhxJd6P0+5C7eRhZnwqYa +n82eXRq0ij6ggvXHvfhxgpa51hCRtEv6MGNu5qJ9QGKxb8VAFbQT3vPI +-----END RSA PRIVATE KEY----- diff --git a/src/test/test_pki/localhost.crt b/src/test/test_pki/localhost.crt new file mode 100644 index 0000000..d4239ba --- /dev/null +++ b/src/test/test_pki/localhost.crt @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIERzCCAi+gAwIBAgIQAtk0UZ5qjqGgxYWL7X9GhDANBgkqhkiG9w0BAQsFADAa +MRgwFgYDVQQDEw9UQ1BUdW5uZWxUZXN0Q0EwHhcNMjIwOTAyMDcwNzUxWhcNNDIw +OTAyMDcwNjEyWjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDLuZElNqvAPIiTBjWJIjD1Ie+Amw1MvsWMY7UP56qC +czkvHI4wfHRJ+mCsUsbKnKR8nYDCa2CiiZpI/oWDZcQZBWmOjaoeBJajw6g+sjFl ++lft4xY6aMSXnpcU71KNelOLZsZmPYs24ZUgmjnQB1s6HZlF1niGabCaNnLtd5z2 +HBPqHno2YvvD4r41n/+kDjhKoZ0t0coZnZaBlEPMvnBOlC1Z/Cn41tORTGkgm3rT ++PY3aS8n2q7prLvMc7QD/4kaN5Ep6IydXYIB+gjwIscgSHEdLZq0rAU1Xk/PQrCc +P3ysdeXFnSq4VuvgVSgXPa4pACvY+cNjaSTzk1WRaLW1AgMBAAGjgY4wgYswDgYD +VR0PAQH/BAQDAgO4MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV +HQ4EFgQU2uwKZmO17EkQ8bLDVMdiTqLlyYEwHwYDVR0jBBgwFoAU+53PiQbh7KSQ +Gc797M71fZg+JDUwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3 +DQEBCwUAA4ICAQAHf8955HzEOTpmdN34O2jVKC1Riu8Zrpv19Gi1AJpi4WJN3xNv +BR6EeaelYEazf17ia5pj3mlT+95aE9wDYVWyqzrJuni5sT94Vw2wIL87qHxFnnBc +Wd2HhTbVSduYlIBOOFpaY28d1td6S2XsiTVfare7z8HESkcP/JeERtAtCnT8NCaC +vxSPdW+fEQxIXssS+PrlOH3rOcZHj8xUD8SDxgiizf0BZw15aLG4YsEhVU8w292K +mBmV0eYcsVpWTplE71zHDc1oJqmCZtLfYjPDy6gzyikkspPDCDU+MLT6y//WJC4d +onY0JZ9CA6i9DKlSsOvQN0LypcYOFdKjWPMwXD0PXy1Mrte4KqexhxlTJfc8WHNt +GhYOCMtYvScHE0T6XD9ybrFb2u+u8TFqrHCfTabJEaCGBsMMK2XwYQvtbRiTjvtB +sTSJrB4fvKfWahYUXZtM4unll752xRjQawW+/Nt7Bi4CeKlQX/6nlpAJTmKDxLCK +OWyS4oNWrcLmVUIKnPiaXA0AsnlOmwuR1Fsrgo+SYJqCeoe90+oo+GdqOmRuSZU9 +N+ry011LZMsNzaHifWqsh1jp3kUQ5XnBA4KWv1Asgg0oCpRnYmUS7GSSdBZkp9a2 +0TEp4yh/gUZ+YO3/XQmpDa1/3kojfhD+WcRQoZ5lwMrlwxtvmiOit4JJQA== +-----END CERTIFICATE----- diff --git a/src/test/test_pki/localhost.key b/src/test/test_pki/localhost.key new file mode 100644 index 0000000..87ef87d --- /dev/null +++ b/src/test/test_pki/localhost.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAy7mRJTarwDyIkwY1iSIw9SHvgJsNTL7FjGO1D+eqgnM5LxyO +MHx0SfpgrFLGypykfJ2AwmtgoomaSP6Fg2XEGQVpjo2qHgSWo8OoPrIxZfpX7eMW +OmjEl56XFO9SjXpTi2bGZj2LNuGVIJo50AdbOh2ZRdZ4hmmwmjZy7Xec9hwT6h56 +NmL7w+K+NZ//pA44SqGdLdHKGZ2WgZRDzL5wTpQtWfwp+NbTkUxpIJt60/j2N2kv +J9qu6ay7zHO0A/+JGjeRKeiMnV2CAfoI8CLHIEhxHS2atKwFNV5Pz0KwnD98rHXl +xZ0quFbr4FUoFz2uKQAr2PnDY2kk85NVkWi1tQIDAQABAoIBAGipZAUPSjtPngaS +iQxzsV0uWwHiJnoIBCt0yf9q0DGGiplGfVIxjfi3ldTSDejngqW2sQCw84ttUAMy +J1ty+8SzACDJbN1RFCb8DMJw/2nZrDS9lpzZWC5gvlN2BB5E+wjB+ylpcsz2JYwD +T7ItJVP9AtJbNb4wLBd945tV+SCCL4wrfaudjDAAXw5YZSIjTucxU4WRm2y8wZ86 +do4J+NscjLpUvuIthfGiui75WGHEdtNu5iveM1dUsQWrIsMxk53D425ovd5Szx6x +6UJBjSwhmIAXxtAwzzrlO/U/4JAyMOHJs+hmCu78bLwjSJBzP/fZzG/KhFm0eyMD +RNMDy4ECgYEA6g42ffOGfP/58IxPk8C+xoRjc2a1TAI/z3ymAxbC+iFYPCiuabXf +twJkTl0yioupq3H0yW6dh2/nTtIpA99L2tEYr44R48LcSD2R5UyE8nYohz+LlOJf +U/vx/p7ao6I8mv7xFI5E52ChvEfkvNwmVcUJlmZ1JswGdwNf4WZzb+ECgYEA3tNc +EXdiWPbkzbOZISJwMyA6S5NqIZm5zoBLtU5ChDoqHQMYE6YmI0stgpNEwEvcmO2C ++9cGvB5mhklrYxxIRL9TzqqUi628/DqSTubBm/Xm+WblRKoDCN0dKK6SS/pkrxWw +YyIGbrCHQXWR1KOlvTvq7uHNXixOvpQVElrmkFUCgYEA6EUUhKeAJlosoi/L5NfZ +Os40l1gswHJW+sQ7R0N2WJ1wn7rLYvJvQYFpI29Pcbgpt48OGjvgroA5rrnWpBYb +g9oPQmCdlkZRLouTVlc6dBcYHyfLkAOaEJEtVL42QT8GH9ayTfDlpiv6NQuvjlB2 +5pTz78JbrhW4sLCznM577mECgYAcThMC8PxgOrSj4K2SBPLlu7FMCmTP8dwlfCyh +0lgmvdC9sLftPwzXLOSSEq0IFFroXjtmTFFBskbpxgfLJjuT6A34Ubje6Wn5TGNr +fGqZqin2AnkbONF73cKneU2CM0N47jNi1F6mzuvPh+THcyZJnIPiZnKVBOHX2a23 +kC57pQKBgQCchLrp2oX0q0jKVb5BqbsJiRMuBhRC96M0IABH6YRaCW372XCvgCWC +jtvXuT0XmqTYbmtpPEw1Pp9eJ3qminK4Z55N2fG+c9wtzJ+Mli8UoS3yFRSzbneD +LtbdqXEoZPYd6dLbTPTe43Pnl45o4epC+46c678nP/TrtfnKAiL1SA== +-----END RSA PRIVATE KEY----- diff --git a/src/test/valid_token_with_custom_increment.rs b/src/test/valid_token_with_custom_increment.rs index c466b74..eb27755 100644 --- a/src/test/valid_token_with_custom_increment.rs +++ b/src/test/valid_token_with_custom_increment.rs @@ -5,7 +5,7 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{ dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, }; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; @@ -14,7 +14,7 @@ fn port(index: u16) -> u16 { } #[tokio::test(flavor = "multi_thread")] -async fn valid_with_token_auth() { +async fn test() { let _ = env_logger::builder().is_test(true).try_init(); // Start internal service @@ -46,8 +46,8 @@ async fn valid_with_token_auth() { // Start client relay task::spawn(crate::tcp_relay_client::run_app(ClientConfig { token: Some(VALID_TOKEN.to_string()), - relay_url: format!("http://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("http://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() })); diff --git a/src/test/valid_with_multiple_token_auth.rs b/src/test/valid_with_multiple_token_auth.rs index 5b03c2e..a5cf9ae 100644 --- a/src/test/valid_with_multiple_token_auth.rs +++ b/src/test/valid_with_multiple_token_auth.rs @@ -5,7 +5,7 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{ dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, }; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; @@ -50,8 +50,8 @@ async fn valid_with_multiple_token_auth() { // Start client relay task::spawn(crate::tcp_relay_client::run_app(ClientConfig { token: Some(VALID_TOKEN.to_string()), - relay_url: format!("http://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("http://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() })); diff --git a/src/test/valid_with_token_auth.rs b/src/test/valid_with_token_auth.rs index bbdb7c9..db33b56 100644 --- a/src/test/valid_with_token_auth.rs +++ b/src/test/valid_with_token_auth.rs @@ -5,7 +5,7 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{ dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, }; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; @@ -46,8 +46,8 @@ async fn valid_with_token_auth() { // Start client relay task::spawn(crate::tcp_relay_client::run_app(ClientConfig { token: Some(VALID_TOKEN.to_string()), - relay_url: format!("http://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("http://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() })); diff --git a/src/test/valid_with_token_auth_and_server_tls.rs b/src/test/valid_with_token_auth_and_server_tls.rs new file mode 100644 index 0000000..4f67a53 --- /dev/null +++ b/src/test/valid_with_token_auth_and_server_tls.rs @@ -0,0 +1,62 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, +}; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidWithTokenAuthAndServerTLS, index) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.root_ca_crt.file_path()), + ..Default::default() + })); + wait_for_port(port(2)).await; + + dummy_tcp_client_square_root_requests(port(2), 10).await; + }) + .await; +} diff --git a/src/test/valid_with_token_auth_multiple_ports.rs b/src/test/valid_with_token_auth_multiple_ports.rs index fc68f4f..e79e6be 100644 --- a/src/test/valid_with_token_auth_multiple_ports.rs +++ b/src/test/valid_with_token_auth_multiple_ports.rs @@ -6,7 +6,7 @@ use crate::test::dummy_tcp_sockets::{ dummy_tcp_client_additions_requests, dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, }; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; const NUM_INC: i32 = 5; @@ -16,7 +16,7 @@ fn port(index: u16) -> u16 { } #[tokio::test(flavor = "multi_thread", worker_threads = 5)] -async fn valid_with_token_auth() { +async fn test() { let _ = env_logger::builder().is_test(true).try_init(); // Start internal services @@ -53,8 +53,8 @@ async fn valid_with_token_auth() { // Start client relay task::spawn(crate::tcp_relay_client::run_app(ClientConfig { token: Some(VALID_TOKEN.to_string()), - relay_url: format!("http://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("http://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() })); diff --git a/src/test/valid_with_token_file.rs b/src/test/valid_with_token_file.rs index e411afe..09bb6af 100644 --- a/src/test/valid_with_token_file.rs +++ b/src/test/valid_with_token_file.rs @@ -5,7 +5,7 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::dummy_tcp_sockets::{ dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, }; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST}; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; const VALID_TOKEN: &str = "AvalidTOKEN"; @@ -49,8 +49,8 @@ async fn valid_with_token_file() { // Start client relay task::spawn(crate::tcp_relay_client::run_app(ClientConfig { token: Some(VALID_TOKEN.to_string()), - relay_url: format!("http://{}:{}", LOCALHOST, port(0)), - listen_address: LOCALHOST.to_string(), + relay_url: format!("http://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), root_certificate: None, ..Default::default() })); diff --git a/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs b/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs new file mode 100644 index 0000000..8e3a3cd --- /dev/null +++ b/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs @@ -0,0 +1,54 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::wait_for_port; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number( + PortsAllocation::WithTokenAuthAndInvalidServerTLSBadCA, + index, + ) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.other_ca_crt.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} diff --git a/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs b/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs new file mode 100644 index 0000000..2ed2a91 --- /dev/null +++ b/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs @@ -0,0 +1,54 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::wait_for_port; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number( + PortsAllocation::WithTokenAuthAndInvalidServerTLSExpiredAndBadCN, + index, + ) +} + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![VALID_TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.expired_client_crt.file_path()), + tls_key: Some(pki.expired_client_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + // Start client relay + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.root_ca_crt.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} -- 2.45.2 From 54214a33083b7c6a5425f3a70ba17c21a4cbfeed Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 10:18:20 +0200 Subject: [PATCH 05/10] Add new test for invalid TLS configuration --- src/base/err_utils.rs | 9 +++- src/tcp_relay_server/mod.rs | 31 ++++++----- src/test/dummy_tcp_sockets.rs | 6 +-- src/test/invalid_token_file.rs | 2 +- src/test/mod.rs | 8 ++- .../server_invalid_tls_config_invalid_cert.rs | 31 +++++++++++ .../server_invalid_tls_config_invalid_key.rs | 31 +++++++++++ ...server_invalid_tls_config_invalid_paths.rs | 53 +++++++++++++++++++ .../server_invalid_tls_config_missing_key.rs | 31 +++++++++++ 9 files changed, 181 insertions(+), 21 deletions(-) create mode 100644 src/test/server_invalid_tls_config_invalid_cert.rs create mode 100644 src/test/server_invalid_tls_config_invalid_key.rs create mode 100644 src/test/server_invalid_tls_config_invalid_paths.rs create mode 100644 src/test/server_invalid_tls_config_missing_key.rs diff --git a/src/base/err_utils.rs b/src/base/err_utils.rs index d9c10a7..1bb1915 100644 --- a/src/base/err_utils.rs +++ b/src/base/err_utils.rs @@ -1,7 +1,12 @@ -use std::error::Error; +use std::fmt::Display; use std::io::ErrorKind; /// Encapsulate errors in [`std::io::Error`] with a message -pub fn encpasulate_error(e: E, msg: &str) -> std::io::Error { +pub fn encpasulate_error(e: E, msg: &str) -> std::io::Error { std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg, e)) } + +/// Create a new [`std::io::Error`] +pub fn new_err(msg: &str) -> std::io::Error { + std::io::Error::new(ErrorKind::Other, msg.to_string()) +} diff --git a/src/tcp_relay_server/mod.rs b/src/tcp_relay_server/mod.rs index 8905c72..39234dc 100644 --- a/src/tcp_relay_server/mod.rs +++ b/src/tcp_relay_server/mod.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use actix_web::web::Data; use actix_web::{middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder}; -use crate::base::err_utils::encpasulate_error; +use crate::base::err_utils::{encpasulate_error, new_err}; use crate::base::{cert_utils, RelayedPort}; use crate::tcp_relay_server::relay_ws::relay_ws; use crate::tcp_relay_server::server_config::ServerConfig; @@ -47,8 +47,7 @@ pub async fn config_route(req: HttpRequest, data: Data>) -> im pub async fn run_app(mut config: ServerConfig) -> std::io::Result<()> { // Check if no port are to be forwarded if config.ports.is_empty() { - log::error!("No port to forward!"); - std::process::exit(2); + return Err(new_err("No port to forward!")); } // Read tokens from file, if any @@ -61,13 +60,17 @@ pub async fn run_app(mut config: ServerConfig) -> std::io::Result<()> { } if !config.has_auth() { - log::error!("No authentication method specified!"); - std::process::exit(3); + return Err(new_err("No authentication method specified!")); + } + + if config.tls_cert.is_some() != config.tls_key.is_some() { + return Err(new_err("Incomplete server TLS configuration!")); } if config.has_tls_client_auth() && !config.has_tls_config() { - log::error!("Cannot provide client auth without TLS configuration!"); - panic!(); + return Err(new_err( + "Cannot provide client auth without TLS configuration!", + )); } let args = Arc::new(config); @@ -75,16 +78,18 @@ pub async fn run_app(mut config: ServerConfig) -> std::io::Result<()> { // Load TLS configuration, if any let tls_config = if let (Some(cert), Some(key)) = (&args.tls_cert, &args.tls_key) { // Load TLS certificate & private key - let cert_file = std::fs::read(cert).expect("Failed to read certificate file"); - let key_file = std::fs::read(key).expect("Failed to read server private key"); + let cert_file = std::fs::read(cert) + .map_err(|e| encpasulate_error(e, "Failed to read certificate file"))?; + let key_file = std::fs::read(key) + .map_err(|e| encpasulate_error(e, "Failed to read server private key"))?; // Get certificates chain - let cert_chain = - cert_utils::parse_pem_certificates(&cert_file).expect("Failed to extract certificates"); + let cert_chain = cert_utils::parse_pem_certificates(&cert_file) + .map_err(|e| encpasulate_error(e, "Failed to extract certificates"))?; // Get private key - let key = - cert_utils::parse_pem_private_key(&key_file).expect("Failed to extract private key!"); + let key = cert_utils::parse_pem_private_key(&key_file) + .map_err(|e| encpasulate_error(e, "Failed to extract private key!"))?; let config = rustls::ServerConfig::builder().with_safe_defaults(); diff --git a/src/test/dummy_tcp_sockets.rs b/src/test/dummy_tcp_sockets.rs index 69cfd36..93b807d 100644 --- a/src/test/dummy_tcp_sockets.rs +++ b/src/test/dummy_tcp_sockets.rs @@ -130,10 +130,10 @@ pub async fn dummy_tcp_client_read_conn(port: u16) -> Vec { .await .expect("Failed to connect to dummy TCP server!"); - let mut buff = Vec::with_capacity(100); - socket.read_to_end(&mut buff).await.unwrap(); + let mut buff: [u8; 100] = [0; 100]; + let size = socket.read(&mut buff).await.unwrap(); - buff + buff[0..size].to_vec() } pub async fn dummy_tcp_client_write_then_read_conn(port: u16, data: &[u8]) -> Vec { diff --git a/src/test/invalid_token_file.rs b/src/test/invalid_token_file.rs index b6f3564..de5846f 100644 --- a/src/test/invalid_token_file.rs +++ b/src/test/invalid_token_file.rs @@ -4,7 +4,7 @@ use crate::test::{get_port_number, PortsAllocation}; const INVALID_TOKEN: &str = "/tmp/a/token/file/that/does/not/exists"; fn port(index: u16) -> u16 { - get_port_number(PortsAllocation::InvalidTokenFile, index) + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) } #[tokio::test(flavor = "multi_thread", worker_threads = 5)] diff --git a/src/test/mod.rs b/src/test/mod.rs index c0f132d..37d8331 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -1,11 +1,11 @@ #[non_exhaustive] enum PortsAllocation { + TestsWithoutPortOpened, DummyTCPServer, ValidWithTokenAuth, InvalidWithTokenAuth, ValidWithMultipleTokenAuth, ValidWithTokenFile, - InvalidTokenFile, ClientTryTLSWhileThereIsNoTLS, ValidTokenWithCustomIncrement, ValidWithTokenAuthMultiplePorts, @@ -15,7 +15,7 @@ enum PortsAllocation { } fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { - 2100 + 20 * (alloc as u16) + index + 30000 + 20 * (alloc as u16) + index } const LOCALHOST_IP: &str = "127.0.0.1"; @@ -27,6 +27,10 @@ mod test_files_utils; mod client_try_tls_while_there_is_no_tls; mod invalid_token_file; mod invalid_with_token_auth; +mod server_invalid_tls_config_invalid_cert; +mod server_invalid_tls_config_invalid_key; +mod server_invalid_tls_config_invalid_paths; +mod server_invalid_tls_config_missing_key; mod valid_token_with_custom_increment; mod valid_with_multiple_token_auth; mod valid_with_token_auth; diff --git a/src/test/server_invalid_tls_config_invalid_cert.rs b/src/test/server_invalid_tls_config_invalid_cert.rs new file mode 100644 index 0000000..f33cc8c --- /dev/null +++ b/src/test/server_invalid_tls_config_invalid_cert.rs @@ -0,0 +1,31 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation}; + +const TOKEN: &str = "mytok"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.root_ca_crl.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/server_invalid_tls_config_invalid_key.rs b/src/test/server_invalid_tls_config_invalid_key.rs new file mode 100644 index 0000000..6bd0788 --- /dev/null +++ b/src/test/server_invalid_tls_config_invalid_key.rs @@ -0,0 +1,31 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation}; + +const TOKEN: &str = "mytok"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.root_ca_crt.file_path()), + tls_key: Some(pki.root_ca_crt.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/server_invalid_tls_config_invalid_paths.rs b/src/test/server_invalid_tls_config_invalid_paths.rs new file mode 100644 index 0000000..fe9922b --- /dev/null +++ b/src/test/server_invalid_tls_config_invalid_paths.rs @@ -0,0 +1,53 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation}; + +const TOKEN: &str = "mytok"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test] +async fn invalid_key_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some("/bad/path/to/key/file".to_string()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn invalid_cert_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some("/bad/path/to/key/file".to_string()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/server_invalid_tls_config_missing_key.rs b/src/test/server_invalid_tls_config_missing_key.rs new file mode 100644 index 0000000..709a3d0 --- /dev/null +++ b/src/test/server_invalid_tls_config_missing_key.rs @@ -0,0 +1,31 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation}; + +const TOKEN: &str = "mytok"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.root_ca_crt.file_path()), + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} -- 2.45.2 From 6f8055f1c7d3a57fe0a4613637c5752df3c59d3b Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 10:21:13 +0200 Subject: [PATCH 06/10] Remove useless tests configuration --- src/test/client_try_tls_while_there_is_no_tls.rs | 2 +- src/test/invalid_token_file.rs | 2 +- src/test/invalid_with_token_auth.rs | 2 +- src/test/server_invalid_tls_config_missing_key.rs | 2 +- src/test/valid_token_with_custom_increment.rs | 2 +- src/test/valid_with_multiple_token_auth.rs | 2 +- src/test/valid_with_token_auth.rs | 2 +- src/test/valid_with_token_auth_and_server_tls.rs | 2 +- src/test/valid_with_token_auth_multiple_ports.rs | 2 +- src/test/valid_with_token_file.rs | 2 +- src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs | 2 +- ...with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/test/client_try_tls_while_there_is_no_tls.rs b/src/test/client_try_tls_while_there_is_no_tls.rs index c4e7b60..881fd45 100644 --- a/src/test/client_try_tls_while_there_is_no_tls.rs +++ b/src/test/client_try_tls_while_there_is_no_tls.rs @@ -11,7 +11,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ClientTryTLSWhileThereIsNoTLS, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/invalid_token_file.rs b/src/test/invalid_token_file.rs index de5846f..6595d3d 100644 --- a/src/test/invalid_token_file.rs +++ b/src/test/invalid_token_file.rs @@ -7,7 +7,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::TestsWithoutPortOpened, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/invalid_with_token_auth.rs b/src/test/invalid_with_token_auth.rs index 3b87aa0..c1d7792 100644 --- a/src/test/invalid_with_token_auth.rs +++ b/src/test/invalid_with_token_auth.rs @@ -12,7 +12,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::InvalidWithTokenAuth, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn invalid_with_token_auth() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/server_invalid_tls_config_missing_key.rs b/src/test/server_invalid_tls_config_missing_key.rs index 709a3d0..b03660a 100644 --- a/src/test/server_invalid_tls_config_missing_key.rs +++ b/src/test/server_invalid_tls_config_missing_key.rs @@ -8,7 +8,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::TestsWithoutPortOpened, index) } -#[tokio::test(flavor = "multi_thread")] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/valid_token_with_custom_increment.rs b/src/test/valid_token_with_custom_increment.rs index eb27755..dcfa49c 100644 --- a/src/test/valid_token_with_custom_increment.rs +++ b/src/test/valid_token_with_custom_increment.rs @@ -13,7 +13,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidTokenWithCustomIncrement, index) } -#[tokio::test(flavor = "multi_thread")] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/valid_with_multiple_token_auth.rs b/src/test/valid_with_multiple_token_auth.rs index a5cf9ae..325ed1a 100644 --- a/src/test/valid_with_multiple_token_auth.rs +++ b/src/test/valid_with_multiple_token_auth.rs @@ -13,7 +13,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidWithTokenFile, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn valid_with_multiple_token_auth() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/valid_with_token_auth.rs b/src/test/valid_with_token_auth.rs index db33b56..4d155af 100644 --- a/src/test/valid_with_token_auth.rs +++ b/src/test/valid_with_token_auth.rs @@ -13,7 +13,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidWithTokenAuth, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn valid_with_token_auth() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/valid_with_token_auth_and_server_tls.rs b/src/test/valid_with_token_auth_and_server_tls.rs index 4f67a53..235aaec 100644 --- a/src/test/valid_with_token_auth_and_server_tls.rs +++ b/src/test/valid_with_token_auth_and_server_tls.rs @@ -14,7 +14,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidWithTokenAuthAndServerTLS, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/valid_with_token_auth_multiple_ports.rs b/src/test/valid_with_token_auth_multiple_ports.rs index e79e6be..c7f565e 100644 --- a/src/test/valid_with_token_auth_multiple_ports.rs +++ b/src/test/valid_with_token_auth_multiple_ports.rs @@ -15,7 +15,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidWithTokenAuthMultiplePorts, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/valid_with_token_file.rs b/src/test/valid_with_token_file.rs index 09bb6af..139698d 100644 --- a/src/test/valid_with_token_file.rs +++ b/src/test/valid_with_token_file.rs @@ -13,7 +13,7 @@ fn port(index: u16) -> u16 { get_port_number(PortsAllocation::ValidWithMultipleTokenAuth, index) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn valid_with_token_file() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs b/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs index 8e3a3cd..4fd6fe4 100644 --- a/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs +++ b/src/test/with_token_auth_and_invalid_server_tls_bad_ca.rs @@ -15,7 +15,7 @@ fn port(index: u16) -> u16 { ) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); diff --git a/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs b/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs index 2ed2a91..c353123 100644 --- a/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs +++ b/src/test/with_token_auth_and_invalid_server_tls_expired_and_bad_cn.rs @@ -15,7 +15,7 @@ fn port(index: u16) -> u16 { ) } -#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[tokio::test()] async fn test() { let _ = env_logger::builder().is_test(true).try_init(); -- 2.45.2 From 019ae92605cd49033e5f0b39c9729003b341c3fc Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 10:42:22 +0200 Subject: [PATCH 07/10] Add new test for client configuration --- src/base/err_utils.rs | 4 +- src/tcp_relay_client/client_config.rs | 29 +++++++------ src/tcp_relay_client/mod.rs | 10 ++--- ...lient_invalid_tls_root_certificate_file.rs | 41 +++++++++++++++++++ src/test/mod.rs | 3 +- ...n_file.rs => server_invalid_token_file.rs} | 0 6 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 src/test/client_invalid_tls_root_certificate_file.rs rename src/test/{invalid_token_file.rs => server_invalid_token_file.rs} (100%) diff --git a/src/base/err_utils.rs b/src/base/err_utils.rs index 1bb1915..6c8a4fa 100644 --- a/src/base/err_utils.rs +++ b/src/base/err_utils.rs @@ -2,8 +2,8 @@ use std::fmt::Display; use std::io::ErrorKind; /// Encapsulate errors in [`std::io::Error`] with a message -pub fn encpasulate_error(e: E, msg: &str) -> std::io::Error { - std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg, e)) +pub fn encpasulate_error(e: E, msg: F) -> std::io::Error { + std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg.to_string(), e)) } /// Create a new [`std::io::Error`] diff --git a/src/tcp_relay_client/client_config.rs b/src/tcp_relay_client/client_config.rs index b0b20a3..3a34913 100644 --- a/src/tcp_relay_client/client_config.rs +++ b/src/tcp_relay_client/client_config.rs @@ -1,3 +1,4 @@ +use crate::base::err_utils::encpasulate_error; use bytes::BufMut; use clap::Parser; @@ -45,21 +46,13 @@ pub struct KeysCache { impl ClientConfig { /// Load certificates and put them in cache - pub fn load_certificates(&mut self) { + pub fn load_certificates(&mut self) -> std::io::Result<()> { self._keys_cache = KeysCache { - _root_certificate_cache: self - .root_certificate - .as_ref() - .map(|c| std::fs::read(c).expect("Failed to read root certificate!")), - _tls_cert_cache: self - .tls_cert - .as_ref() - .map(|c| std::fs::read(c).expect("Failed to read client certificate!")), - _tls_key_cache: self - .tls_key - .as_ref() - .map(|c| std::fs::read(c).expect("Failed to read client key!")), + _root_certificate_cache: load_pem_file(&self.root_certificate, "root certificate")?, + _tls_cert_cache: load_pem_file(&self.tls_cert, "client certificate")?, + _tls_key_cache: load_pem_file(&self.tls_cert, "client key")?, }; + Ok(()) } /// Get client token, returning a dummy token if none was specified @@ -95,6 +88,16 @@ impl ClientConfig { } } +fn load_pem_file(path: &Option, name: &str) -> std::io::Result>> { + Ok(match path { + None => None, + Some(p) => Some( + std::fs::read(p) + .map_err(|e| encpasulate_error(e, format!("Failed to load {}!", name)))?, + ), + }) +} + #[cfg(test)] mod test { use crate::tcp_relay_client::client_config::ClientConfig; diff --git a/src/tcp_relay_client/mod.rs b/src/tcp_relay_client/mod.rs index 6ca6424..6ba55ce 100644 --- a/src/tcp_relay_client/mod.rs +++ b/src/tcp_relay_client/mod.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use futures::future::join_all; use reqwest::{Certificate, Identity}; +use crate::base::err_utils::new_err; use crate::base::RemoteConfig; use crate::tcp_relay_client::client_config::ClientConfig; use crate::tcp_relay_client::relay_client::relay_client; @@ -54,15 +55,14 @@ async fn get_server_config(conf: &ClientConfig) -> Result std::io::Result<()> { - args.load_certificates(); + args.load_certificates()?; let args = Arc::new(args); // Check arguments coherence if args.tls_cert.is_some() != args.tls_key.is_some() { - log::error!( - "If you specify one of TLS certificate / key, you must then specify the other!" - ); - panic!(); + return Err(new_err( + "If you specify one of TLS certificate / key, you must then specify the other!", + )); } if args.get_client_keypair().is_some() { diff --git a/src/test/client_invalid_tls_root_certificate_file.rs b/src/test/client_invalid_tls_root_certificate_file.rs new file mode 100644 index 0000000..4a0d59b --- /dev/null +++ b/src/test/client_invalid_tls_root_certificate_file.rs @@ -0,0 +1,41 @@ +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +const VALID_TOKEN: &str = "AvalidTOKEN"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test()] +async fn invalid_file_type() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.expired_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn non_existing_file() { + let _ = env_logger::builder().is_test(true).try_init(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some("/bad/path/to/file".to_string()), + ..Default::default() + }) + .await + .unwrap_err(); +} diff --git a/src/test/mod.rs b/src/test/mod.rs index 37d8331..15551b8 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -24,13 +24,14 @@ mod dummy_tcp_sockets; mod pki; mod test_files_utils; +mod client_invalid_tls_root_certificate_file; mod client_try_tls_while_there_is_no_tls; -mod invalid_token_file; mod invalid_with_token_auth; mod server_invalid_tls_config_invalid_cert; mod server_invalid_tls_config_invalid_key; mod server_invalid_tls_config_invalid_paths; mod server_invalid_tls_config_missing_key; +mod server_invalid_token_file; mod valid_token_with_custom_increment; mod valid_with_multiple_token_auth; mod valid_with_token_auth; diff --git a/src/test/invalid_token_file.rs b/src/test/server_invalid_token_file.rs similarity index 100% rename from src/test/invalid_token_file.rs rename to src/test/server_invalid_token_file.rs -- 2.45.2 From 4f89bc06a0cd6df625c55b96aba8b50465d2ccf2 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 10:57:53 +0200 Subject: [PATCH 08/10] Add new test for TLS mutual authentication --- src/tcp_relay_client/client_config.rs | 2 +- src/tcp_relay_server/mod.rs | 2 +- .../tls_cert_client_verifier.rs | 33 ++++++---- src/test/mod.rs | 2 + ...server_invalid_tls_config_invalid_paths.rs | 50 ++++++++++++++- src/test/valid_with_tls_auth.rs | 61 +++++++++++++++++++ 6 files changed, 134 insertions(+), 16 deletions(-) create mode 100644 src/test/valid_with_tls_auth.rs diff --git a/src/tcp_relay_client/client_config.rs b/src/tcp_relay_client/client_config.rs index 3a34913..fd47190 100644 --- a/src/tcp_relay_client/client_config.rs +++ b/src/tcp_relay_client/client_config.rs @@ -50,7 +50,7 @@ impl ClientConfig { self._keys_cache = KeysCache { _root_certificate_cache: load_pem_file(&self.root_certificate, "root certificate")?, _tls_cert_cache: load_pem_file(&self.tls_cert, "client certificate")?, - _tls_key_cache: load_pem_file(&self.tls_cert, "client key")?, + _tls_key_cache: load_pem_file(&self.tls_key, "client key")?, }; Ok(()) } diff --git a/src/tcp_relay_server/mod.rs b/src/tcp_relay_server/mod.rs index 39234dc..7df9054 100644 --- a/src/tcp_relay_server/mod.rs +++ b/src/tcp_relay_server/mod.rs @@ -95,7 +95,7 @@ pub async fn run_app(mut config: ServerConfig) -> std::io::Result<()> { let config = match args.has_tls_client_auth() { true => config - .with_client_cert_verifier(Arc::new(CustomCertClientVerifier::new(args.clone()))), + .with_client_cert_verifier(Arc::new(CustomCertClientVerifier::new(args.clone())?)), false => config.with_no_client_auth(), }; diff --git a/src/tcp_relay_server/tls_cert_client_verifier.rs b/src/tcp_relay_server/tls_cert_client_verifier.rs index 806b9b7..07996fe 100644 --- a/src/tcp_relay_server/tls_cert_client_verifier.rs +++ b/src/tcp_relay_server/tls_cert_client_verifier.rs @@ -7,7 +7,7 @@ use rustls::{Certificate, DistinguishedNames, Error, RootCertStore}; use x509_parser::prelude::{CertificateRevocationList, FromDer, X509Certificate}; use crate::base::cert_utils::parse_pem_certificates; - +use crate::base::err_utils::{encpasulate_error, new_err}; use crate::tcp_relay_server::server_config::ServerConfig; pub struct CustomCertClientVerifier { @@ -16,21 +16,28 @@ pub struct CustomCertClientVerifier { } impl CustomCertClientVerifier { - pub fn new(conf: Arc) -> Self { + pub fn new(conf: Arc) -> std::io::Result { // Build root certifications list let cert_path = conf .tls_client_auth_root_cert .as_deref() .expect("No root certificates for client authentication provided!"); - let cert_file = std::fs::read(cert_path) - .expect("Failed to read root certificates for client authentication!"); + let cert_file = std::fs::read(cert_path).map_err(|e| { + encpasulate_error( + e, + "Failed to read root certificates for client authentication!", + ) + })?; - let root_certs = parse_pem_certificates(&cert_file) - .expect("Failed to read root certificates for server authentication!"); + let root_certs = parse_pem_certificates(&cert_file).map_err(|e| { + encpasulate_error( + e, + "Failed to read root certificates for server authentication!", + ) + })?; if root_certs.is_empty() { - log::error!("No certificates found for client authentication!"); - panic!(); + return Err(new_err("No certificates found for client authentication!")); } let mut store = RootCertStore::empty(); @@ -42,19 +49,21 @@ impl CustomCertClientVerifier { // Parse CRL file (if any) let crl = if let Some(crl_file) = &conf.tls_revocation_list { - let crl_file = std::fs::read(crl_file).expect("Failed to open / read CRL file!"); + let crl_file = std::fs::read(crl_file) + .map_err(|e| encpasulate_error(e, "Failed to open / read CRL file!"))?; - let parsed_crl = pem::parse(crl_file).expect("Failed to decode CRL file!"); + let parsed_crl = pem::parse(crl_file) + .map_err(|e| encpasulate_error(e, "Failed to decode CRL file!"))?; Some(parsed_crl.contents) } else { None }; - Self { + Ok(Self { upstream_cert_verifier: Box::new(AllowAnyAuthenticatedClient::new(store)), crl, - } + }) } } diff --git a/src/test/mod.rs b/src/test/mod.rs index 15551b8..9975407 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -3,6 +3,7 @@ enum PortsAllocation { TestsWithoutPortOpened, DummyTCPServer, ValidWithTokenAuth, + ValidWithTLSAuth, InvalidWithTokenAuth, ValidWithMultipleTokenAuth, ValidWithTokenFile, @@ -34,6 +35,7 @@ mod server_invalid_tls_config_missing_key; mod server_invalid_token_file; mod valid_token_with_custom_increment; mod valid_with_multiple_token_auth; +mod valid_with_tls_auth; mod valid_with_token_auth; mod valid_with_token_auth_and_server_tls; mod valid_with_token_auth_multiple_ports; diff --git a/src/test/server_invalid_tls_config_invalid_paths.rs b/src/test/server_invalid_tls_config_invalid_paths.rs index fe9922b..1977cf5 100644 --- a/src/test/server_invalid_tls_config_invalid_paths.rs +++ b/src/test/server_invalid_tls_config_invalid_paths.rs @@ -4,6 +4,8 @@ use crate::test::{get_port_number, PortsAllocation}; const TOKEN: &str = "mytok"; +const BAD_PATH: &str = "/bad/path/to/key/file"; + fn port(index: u16) -> u16 { get_port_number(PortsAllocation::TestsWithoutPortOpened, index) } @@ -22,7 +24,7 @@ async fn invalid_key_path() { listen_address: format!("127.0.0.1:{}", port(0)), increment_ports: 1, tls_cert: Some(pki.localhost_crt.file_path()), - tls_key: Some("/bad/path/to/key/file".to_string()), + tls_key: Some(BAD_PATH.to_string()), tls_client_auth_root_cert: None, tls_revocation_list: None, }) @@ -43,7 +45,7 @@ async fn invalid_cert_path() { upstream_server: "127.0.0.1".to_string(), listen_address: format!("127.0.0.1:{}", port(0)), increment_ports: 1, - tls_cert: Some("/bad/path/to/key/file".to_string()), + tls_cert: Some(BAD_PATH.to_string()), tls_key: Some(pki.localhost_key.file_path()), tls_client_auth_root_cert: None, tls_revocation_list: None, @@ -51,3 +53,47 @@ async fn invalid_cert_path() { .await .unwrap_err(); } + +#[tokio::test] +async fn invalid_client_root_cert_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(BAD_PATH.to_string()), + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn invalid_client_root_crl_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crl.file_path()), + tls_revocation_list: Some(BAD_PATH.to_string()), + }) + .await + .unwrap_err(); +} diff --git a/src/test/valid_with_tls_auth.rs b/src/test/valid_with_tls_auth.rs new file mode 100644 index 0000000..ac2686b --- /dev/null +++ b/src/test/valid_with_tls_auth.rs @@ -0,0 +1,61 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{ + dummy_tcp_client_square_root_requests, wait_for_port, DummyTCPServer, +}; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ValidWithTLSAuth, index) +} + +#[tokio::test] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crt.file_path()), + tls_revocation_list: Some(pki.root_ca_crl.file_path()), + })); + wait_for_port(port(0)).await; + + // Start client relay + task::spawn(crate::tcp_relay_client::run_app(ClientConfig { + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.root_ca_crt.file_path()), + tls_cert: Some(pki.valid_client_crt.file_path()), + tls_key: Some(pki.valid_client_key.file_path()), + ..Default::default() + })); + wait_for_port(port(2)).await; + + dummy_tcp_client_square_root_requests(port(2), 10).await; + }) + .await; +} -- 2.45.2 From a5e48cf9d0c2c593b1d325638eedd2fae9576c43 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 14:14:05 +0200 Subject: [PATCH 09/10] Add TLS invalid cases checks --- src/test/expired_certificate.rs | 0 src/test/mod.rs | 7 +++ src/test/server_missing_auth.rs | 71 ++++++++++++++++++++++++ src/test/tls_auth_expired_certificate.rs | 58 +++++++++++++++++++ src/test/tls_auth_invalid_certificate.rs | 58 +++++++++++++++++++ src/test/tls_auth_revoked_certificate.rs | 58 +++++++++++++++++++ 6 files changed, 252 insertions(+) create mode 100644 src/test/expired_certificate.rs create mode 100644 src/test/server_missing_auth.rs create mode 100644 src/test/tls_auth_expired_certificate.rs create mode 100644 src/test/tls_auth_invalid_certificate.rs create mode 100644 src/test/tls_auth_revoked_certificate.rs diff --git a/src/test/expired_certificate.rs b/src/test/expired_certificate.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/test/mod.rs b/src/test/mod.rs index 9975407..708f5ee 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -13,6 +13,9 @@ enum PortsAllocation { ValidWithTokenAuthAndServerTLS, WithTokenAuthAndInvalidServerTLSBadCA, WithTokenAuthAndInvalidServerTLSExpiredAndBadCN, + TlsAuthExpiredClientCertificate, + TlsAuthRevokedClientCertificate, + TlsAuthInvalidClientCertificate, } fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { @@ -33,6 +36,10 @@ mod server_invalid_tls_config_invalid_key; mod server_invalid_tls_config_invalid_paths; mod server_invalid_tls_config_missing_key; mod server_invalid_token_file; +mod server_missing_auth; +mod tls_auth_expired_certificate; +mod tls_auth_invalid_certificate; +mod tls_auth_revoked_certificate; mod valid_token_with_custom_increment; mod valid_with_multiple_token_auth; mod valid_with_tls_auth; diff --git a/src/test/server_missing_auth.rs b/src/test/server_missing_auth.rs new file mode 100644 index 0000000..9882624 --- /dev/null +++ b/src/test/server_missing_auth.rs @@ -0,0 +1,71 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation}; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test] +async fn with_tls_server() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.root_ca_crl.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn without_tls_server() { + let _ = env_logger::builder().is_test(true).try_init(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn tls_auth_without_tls_config() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: None, + tls_client_auth_root_cert: Some(pki.root_ca_crt.file_path()), + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/tls_auth_expired_certificate.rs b/src/test/tls_auth_expired_certificate.rs new file mode 100644 index 0000000..1d80ed3 --- /dev/null +++ b/src/test/tls_auth_expired_certificate.rs @@ -0,0 +1,58 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TlsAuthExpiredClientCertificate, index) +} + +#[tokio::test] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crt.file_path()), + tls_revocation_list: Some(pki.root_ca_crl.file_path()), + })); + wait_for_port(port(0)).await; + + // Start client relay + crate::tcp_relay_client::run_app(ClientConfig { + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.root_ca_crt.file_path()), + tls_cert: Some(pki.expired_client_crt.file_path()), + tls_key: Some(pki.valid_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} diff --git a/src/test/tls_auth_invalid_certificate.rs b/src/test/tls_auth_invalid_certificate.rs new file mode 100644 index 0000000..b3ac947 --- /dev/null +++ b/src/test/tls_auth_invalid_certificate.rs @@ -0,0 +1,58 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TlsAuthInvalidClientCertificate, index) +} + +#[tokio::test] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.other_ca_crt.file_path()), + tls_revocation_list: Some(pki.other_ca_crl.file_path()), + })); + wait_for_port(port(0)).await; + + // Start client relay + crate::tcp_relay_client::run_app(ClientConfig { + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.root_ca_crt.file_path()), + tls_cert: Some(pki.revoked_client_crt.file_path()), + tls_key: Some(pki.revoked_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} diff --git a/src/test/tls_auth_revoked_certificate.rs b/src/test/tls_auth_revoked_certificate.rs new file mode 100644 index 0000000..bedaec2 --- /dev/null +++ b/src/test/tls_auth_revoked_certificate.rs @@ -0,0 +1,58 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::dummy_tcp_sockets::{wait_for_port, DummyTCPServer}; +use crate::test::pki::Pki; +use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TlsAuthRevokedClientCertificate, index) +} + +#[tokio::test] +async fn test() { + let _ = env_logger::builder().is_test(true).try_init(); + + // Start internal service + let local_server = DummyTCPServer::start(port(1)).await; + tokio::spawn(async move { + local_server.loop_conn_square_operations().await; + }); + + let pki = Pki::load(); + + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + wait_for_port(port(1)).await; + + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crt.file_path()), + tls_revocation_list: Some(pki.root_ca_crl.file_path()), + })); + wait_for_port(port(0)).await; + + // Start client relay + crate::tcp_relay_client::run_app(ClientConfig { + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(pki.root_ca_crt.file_path()), + tls_cert: Some(pki.revoked_client_crt.file_path()), + tls_key: Some(pki.revoked_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); + }) + .await; +} -- 2.45.2 From 59aadeacd4eece14db90bff70b1b6e1d7d31a458 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Fri, 2 Sep 2022 15:01:34 +0200 Subject: [PATCH 10/10] Add more configuration tests --- src/base/err_utils.rs | 2 +- src/main.rs | 11 ++ src/tcp_relay_client/mod.rs | 7 +- src/test/client_invalid_tls_configuration.rs | 159 ++++++++++++++++++ ...lient_invalid_tls_root_certificate_file.rs | 30 +++- src/test/mod.rs | 7 +- .../server_invalid_tls_config_invalid_cert.rs | 73 +++++++- ...r_invalid_tls_config_invalid_client_crl.rs | 78 +++++++++ ...id_tls_config_invalid_client_root_cert.rs} | 79 ++++----- .../server_invalid_tls_config_invalid_key.rs | 73 +++++++- .../server_invalid_tls_config_missing_key.rs | 31 ---- src/test/test_files_utils.rs | 10 ++ 12 files changed, 463 insertions(+), 97 deletions(-) create mode 100644 src/test/client_invalid_tls_configuration.rs create mode 100644 src/test/server_invalid_tls_config_invalid_client_crl.rs rename src/test/{server_invalid_tls_config_invalid_paths.rs => server_invalid_tls_config_invalid_client_root_cert.rs} (69%) delete mode 100644 src/test/server_invalid_tls_config_missing_key.rs diff --git a/src/base/err_utils.rs b/src/base/err_utils.rs index 6c8a4fa..11ee6a4 100644 --- a/src/base/err_utils.rs +++ b/src/base/err_utils.rs @@ -3,7 +3,7 @@ use std::io::ErrorKind; /// Encapsulate errors in [`std::io::Error`] with a message pub fn encpasulate_error(e: E, msg: F) -> std::io::Error { - std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg.to_string(), e)) + std::io::Error::new(ErrorKind::Other, format!("{}:\n* {}", msg.to_string(), e)) } /// Create a new [`std::io::Error`] diff --git a/src/main.rs b/src/main.rs index 1b00bdc..9872322 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,3 +36,14 @@ async fn main() -> std::io::Result<()> { SubCommands::Client(c) => tcp_over_http::tcp_relay_client::run_app(c).await, } } + +#[cfg(test)] +mod test { + use crate::CliArgs; + + #[test] + fn verify_cli() { + use clap::CommandFactory; + CliArgs::command().debug_assert() + } +} diff --git a/src/tcp_relay_client/mod.rs b/src/tcp_relay_client/mod.rs index 6ba55ce..3c688b0 100644 --- a/src/tcp_relay_client/mod.rs +++ b/src/tcp_relay_client/mod.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use futures::future::join_all; use reqwest::{Certificate, Identity}; -use crate::base::err_utils::new_err; +use crate::base::err_utils::{encpasulate_error, new_err}; use crate::base::RemoteConfig; use crate::tcp_relay_client::client_config::ClientConfig; use crate::tcp_relay_client::relay_client::relay_client; @@ -29,7 +29,8 @@ async fn get_server_config(conf: &ClientConfig) -> Result std::io::Result<()> { port.id, urlencoding::encode(args.get_auth_token()) ) - .replace("http", "ws"), + .replace("http", "ws"), listen_address, args.clone(), )); diff --git a/src/test/client_invalid_tls_configuration.rs b/src/test/client_invalid_tls_configuration.rs new file mode 100644 index 0000000..30ebeb0 --- /dev/null +++ b/src/test/client_invalid_tls_configuration.rs @@ -0,0 +1,159 @@ +use tokio::task; + +use crate::tcp_relay_client::client_config::ClientConfig; +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::{BAD_PATH, get_port_number, LOCALHOST_IP, PortsAllocation}; +use crate::test::dummy_tcp_sockets::wait_for_port; +use crate::test::pki::Pki; +use crate::test::test_files_utils::create_temp_file_with_random_content; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::ClientInvalidTlsConfiguration, index) +} + +#[tokio::test()] +async fn random_file_for_cert() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + let random_file = create_temp_file_with_random_content(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(random_file.to_string_lossy().to_string()), + tls_key: Some(pki.valid_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn random_file_for_key() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + let random_file = create_temp_file_with_random_content(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(pki.valid_client_crt.file_path()), + tls_key: Some(random_file.to_string_lossy().to_string()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn bad_pem_file_for_cert() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(pki.root_ca_crl.file_path()), + tls_key: Some(pki.valid_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn bad_pem_file_for_key() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(pki.valid_client_crt.file_path()), + tls_key: Some(pki.root_ca_crl.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn non_existing_cert() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(BAD_PATH.to_string()), + tls_key: Some(pki.valid_client_key.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn non_existing_key() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(pki.valid_client_crt.file_path()), + tls_key: Some(BAD_PATH.to_string()), + ..Default::default() + }) + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn unmatched_key_cert_pair() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + let local_set = task::LocalSet::new(); + local_set + .run_until(async move { + // Start server relay + task::spawn_local(crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec!["dqsd".to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crt.file_path()), + tls_revocation_list: None, + })); + wait_for_port(port(0)).await; + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some("token".to_string()), + relay_url: format!("https://localhost:{}", port(0)), + listen_address: LOCALHOST_IP.to_string(), + tls_cert: Some(pki.valid_client_crt.file_path()), + tls_key: Some(pki.revoked_client_key.file_path()), + root_certificate: Some(pki.root_ca_crt.file_path()), + ..Default::default() + }) + .await + .unwrap_err(); + }).await; +} \ No newline at end of file diff --git a/src/test/client_invalid_tls_root_certificate_file.rs b/src/test/client_invalid_tls_root_certificate_file.rs index 4a0d59b..bcd080f 100644 --- a/src/test/client_invalid_tls_root_certificate_file.rs +++ b/src/test/client_invalid_tls_root_certificate_file.rs @@ -1,6 +1,7 @@ use crate::tcp_relay_client::client_config::ClientConfig; +use crate::test::{BAD_PATH, get_port_number, LOCALHOST_IP, PortsAllocation}; use crate::test::pki::Pki; -use crate::test::{get_port_number, PortsAllocation, LOCALHOST_IP}; +use crate::test::test_files_utils::create_temp_file_with_random_content; const VALID_TOKEN: &str = "AvalidTOKEN"; @@ -21,8 +22,8 @@ async fn invalid_file_type() { root_certificate: Some(pki.expired_client_key.file_path()), ..Default::default() }) - .await - .unwrap_err(); + .await + .unwrap_err(); } #[tokio::test()] @@ -33,9 +34,26 @@ async fn non_existing_file() { token: Some(VALID_TOKEN.to_string()), relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), listen_address: LOCALHOST_IP.to_string(), - root_certificate: Some("/bad/path/to/file".to_string()), + root_certificate: Some(BAD_PATH.to_string()), ..Default::default() }) - .await - .unwrap_err(); + .await + .unwrap_err(); +} + +#[tokio::test()] +async fn random_file() { + let _ = env_logger::builder().is_test(true).try_init(); + + let random_file = create_temp_file_with_random_content(); + + crate::tcp_relay_client::run_app(ClientConfig { + token: Some(VALID_TOKEN.to_string()), + relay_url: format!("https://{}:{}", LOCALHOST_IP, port(0)), + listen_address: LOCALHOST_IP.to_string(), + root_certificate: Some(random_file.to_string_lossy().to_string()), + ..Default::default() + }) + .await + .unwrap_err(); } diff --git a/src/test/mod.rs b/src/test/mod.rs index 708f5ee..1c44edc 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -16,6 +16,7 @@ enum PortsAllocation { TlsAuthExpiredClientCertificate, TlsAuthRevokedClientCertificate, TlsAuthInvalidClientCertificate, + ClientInvalidTlsConfiguration, } fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { @@ -23,6 +24,7 @@ fn get_port_number(alloc: PortsAllocation, index: u16) -> u16 { } const LOCALHOST_IP: &str = "127.0.0.1"; +const BAD_PATH: &str = "/bad/path/to/key/file"; mod dummy_tcp_sockets; mod pki; @@ -30,11 +32,12 @@ mod test_files_utils; mod client_invalid_tls_root_certificate_file; mod client_try_tls_while_there_is_no_tls; +mod client_invalid_tls_configuration; mod invalid_with_token_auth; mod server_invalid_tls_config_invalid_cert; +mod server_invalid_tls_config_invalid_client_crl; +mod server_invalid_tls_config_invalid_client_root_cert; mod server_invalid_tls_config_invalid_key; -mod server_invalid_tls_config_invalid_paths; -mod server_invalid_tls_config_missing_key; mod server_invalid_token_file; mod server_missing_auth; mod tls_auth_expired_certificate; diff --git a/src/test/server_invalid_tls_config_invalid_cert.rs b/src/test/server_invalid_tls_config_invalid_cert.rs index f33cc8c..6e4ab2d 100644 --- a/src/test/server_invalid_tls_config_invalid_cert.rs +++ b/src/test/server_invalid_tls_config_invalid_cert.rs @@ -1,6 +1,7 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::pki::Pki; -use crate::test::{get_port_number, PortsAllocation}; +use crate::test::test_files_utils::create_temp_file_with_random_content; +use crate::test::{get_port_number, PortsAllocation, BAD_PATH}; const TOKEN: &str = "mytok"; @@ -9,7 +10,29 @@ fn port(index: u16) -> u16 { } #[tokio::test] -async fn test() { +async fn unspecified() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: None, + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn incorrect_pem_type() { let _ = env_logger::builder().is_test(true).try_init(); let pki = Pki::load(); @@ -29,3 +52,49 @@ async fn test() { .await .unwrap_err(); } + +#[tokio::test] +async fn random_contents() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + let random_file = create_temp_file_with_random_content(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(random_file.to_string_lossy().to_string()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn invalid_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(BAD_PATH.to_string()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/server_invalid_tls_config_invalid_client_crl.rs b/src/test/server_invalid_tls_config_invalid_client_crl.rs new file mode 100644 index 0000000..ad63b8d --- /dev/null +++ b/src/test/server_invalid_tls_config_invalid_client_crl.rs @@ -0,0 +1,78 @@ +use crate::tcp_relay_server::server_config::ServerConfig; +use crate::test::pki::Pki; +use crate::test::test_files_utils::create_temp_file_with_random_content; +use crate::test::{get_port_number, PortsAllocation, BAD_PATH}; + +const TOKEN: &str = "mytok"; + +fn port(index: u16) -> u16 { + get_port_number(PortsAllocation::TestsWithoutPortOpened, index) +} + +#[tokio::test] +async fn bad_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crl.file_path()), + tls_revocation_list: Some(BAD_PATH.to_string()), + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn random_content() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + let random_file = create_temp_file_with_random_content(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crl.file_path()), + tls_revocation_list: Some(random_file.to_string_lossy().to_string()), + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn invalid_pem() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(pki.root_ca_crl.file_path()), + tls_revocation_list: Some(pki.root_ca_crt.file_path()), + }) + .await + .unwrap_err(); +} diff --git a/src/test/server_invalid_tls_config_invalid_paths.rs b/src/test/server_invalid_tls_config_invalid_client_root_cert.rs similarity index 69% rename from src/test/server_invalid_tls_config_invalid_paths.rs rename to src/test/server_invalid_tls_config_invalid_client_root_cert.rs index 1977cf5..ac387d5 100644 --- a/src/test/server_invalid_tls_config_invalid_paths.rs +++ b/src/test/server_invalid_tls_config_invalid_client_root_cert.rs @@ -1,61 +1,16 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::pki::Pki; -use crate::test::{get_port_number, PortsAllocation}; +use crate::test::test_files_utils::create_temp_file_with_random_content; +use crate::test::{get_port_number, PortsAllocation, BAD_PATH}; const TOKEN: &str = "mytok"; -const BAD_PATH: &str = "/bad/path/to/key/file"; - fn port(index: u16) -> u16 { get_port_number(PortsAllocation::TestsWithoutPortOpened, index) } #[tokio::test] -async fn invalid_key_path() { - let _ = env_logger::builder().is_test(true).try_init(); - - let pki = Pki::load(); - - crate::tcp_relay_server::run_app(ServerConfig { - tokens: vec![TOKEN.to_string()], - tokens_file: None, - ports: vec![port(1)], - upstream_server: "127.0.0.1".to_string(), - listen_address: format!("127.0.0.1:{}", port(0)), - increment_ports: 1, - tls_cert: Some(pki.localhost_crt.file_path()), - tls_key: Some(BAD_PATH.to_string()), - tls_client_auth_root_cert: None, - tls_revocation_list: None, - }) - .await - .unwrap_err(); -} - -#[tokio::test] -async fn invalid_cert_path() { - let _ = env_logger::builder().is_test(true).try_init(); - - let pki = Pki::load(); - - crate::tcp_relay_server::run_app(ServerConfig { - tokens: vec![TOKEN.to_string()], - tokens_file: None, - ports: vec![port(1)], - upstream_server: "127.0.0.1".to_string(), - listen_address: format!("127.0.0.1:{}", port(0)), - increment_ports: 1, - tls_cert: Some(BAD_PATH.to_string()), - tls_key: Some(pki.localhost_key.file_path()), - tls_client_auth_root_cert: None, - tls_revocation_list: None, - }) - .await - .unwrap_err(); -} - -#[tokio::test] -async fn invalid_client_root_cert_path() { +async fn invalid_path() { let _ = env_logger::builder().is_test(true).try_init(); let pki = Pki::load(); @@ -77,7 +32,7 @@ async fn invalid_client_root_cert_path() { } #[tokio::test] -async fn invalid_client_root_crl_path() { +async fn other_pem_file_type() { let _ = env_logger::builder().is_test(true).try_init(); let pki = Pki::load(); @@ -92,7 +47,31 @@ async fn invalid_client_root_crl_path() { tls_cert: Some(pki.localhost_crt.file_path()), tls_key: Some(pki.localhost_key.file_path()), tls_client_auth_root_cert: Some(pki.root_ca_crl.file_path()), - tls_revocation_list: Some(BAD_PATH.to_string()), + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn random_content() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + let random_file = create_temp_file_with_random_content(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(pki.localhost_key.file_path()), + tls_client_auth_root_cert: Some(random_file.to_string_lossy().to_string()), + tls_revocation_list: None, }) .await .unwrap_err(); diff --git a/src/test/server_invalid_tls_config_invalid_key.rs b/src/test/server_invalid_tls_config_invalid_key.rs index 6bd0788..98a9e22 100644 --- a/src/test/server_invalid_tls_config_invalid_key.rs +++ b/src/test/server_invalid_tls_config_invalid_key.rs @@ -1,6 +1,7 @@ use crate::tcp_relay_server::server_config::ServerConfig; use crate::test::pki::Pki; -use crate::test::{get_port_number, PortsAllocation}; +use crate::test::test_files_utils::create_temp_file_with_random_content; +use crate::test::{get_port_number, PortsAllocation, BAD_PATH}; const TOKEN: &str = "mytok"; @@ -9,7 +10,7 @@ fn port(index: u16) -> u16 { } #[tokio::test] -async fn test() { +async fn invalid_pem_file_type() { let _ = env_logger::builder().is_test(true).try_init(); let pki = Pki::load(); @@ -29,3 +30,71 @@ async fn test() { .await .unwrap_err(); } + +#[tokio::test()] +async fn unspecified() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.root_ca_crt.file_path()), + tls_key: None, + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn random_content() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + let random_content = create_temp_file_with_random_content(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.root_ca_crt.file_path()), + tls_key: Some(random_content.to_string_lossy().to_string()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} + +#[tokio::test] +async fn invalid_path() { + let _ = env_logger::builder().is_test(true).try_init(); + + let pki = Pki::load(); + + crate::tcp_relay_server::run_app(ServerConfig { + tokens: vec![TOKEN.to_string()], + tokens_file: None, + ports: vec![port(1)], + upstream_server: "127.0.0.1".to_string(), + listen_address: format!("127.0.0.1:{}", port(0)), + increment_ports: 1, + tls_cert: Some(pki.localhost_crt.file_path()), + tls_key: Some(BAD_PATH.to_string()), + tls_client_auth_root_cert: None, + tls_revocation_list: None, + }) + .await + .unwrap_err(); +} diff --git a/src/test/server_invalid_tls_config_missing_key.rs b/src/test/server_invalid_tls_config_missing_key.rs deleted file mode 100644 index b03660a..0000000 --- a/src/test/server_invalid_tls_config_missing_key.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::tcp_relay_server::server_config::ServerConfig; -use crate::test::pki::Pki; -use crate::test::{get_port_number, PortsAllocation}; - -const TOKEN: &str = "mytok"; - -fn port(index: u16) -> u16 { - get_port_number(PortsAllocation::TestsWithoutPortOpened, index) -} - -#[tokio::test()] -async fn test() { - let _ = env_logger::builder().is_test(true).try_init(); - - let pki = Pki::load(); - - crate::tcp_relay_server::run_app(ServerConfig { - tokens: vec![TOKEN.to_string()], - tokens_file: None, - ports: vec![port(1)], - upstream_server: "127.0.0.1".to_string(), - listen_address: format!("127.0.0.1:{}", port(0)), - increment_ports: 1, - tls_cert: Some(pki.root_ca_crt.file_path()), - tls_key: None, - tls_client_auth_root_cert: None, - tls_revocation_list: None, - }) - .await - .unwrap_err(); -} diff --git a/src/test/test_files_utils.rs b/src/test/test_files_utils.rs index e7d305d..95ecea1 100644 --- a/src/test/test_files_utils.rs +++ b/src/test/test_files_utils.rs @@ -1,7 +1,17 @@ use mktemp::Temp; +use rand::Rng; +/// Create a temporary file and feed it with some specified content pub fn create_temp_file_with_content(content: &[u8]) -> Temp { let temp = Temp::new_file().unwrap(); std::fs::write(&temp, content).unwrap(); temp } + +/// Generate a temporary file with some random content +pub fn create_temp_file_with_random_content() -> Temp { + let random_bytes = rand::thread_rng().gen::<[u8; 10]>(); + let temp = Temp::new_file().unwrap(); + std::fs::write(&temp, random_bytes).unwrap(); + temp +} -- 2.45.2