Add new test for client configuration
This commit is contained in:
		@@ -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: Display>(e: E, msg: &str) -> std::io::Error {
 | 
			
		||||
    std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg, e))
 | 
			
		||||
pub fn encpasulate_error<E: Display, F: ToString>(e: E, msg: F) -> std::io::Error {
 | 
			
		||||
    std::io::Error::new(ErrorKind::Other, format!("{}: {}", msg.to_string(), e))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Create a new [`std::io::Error`]
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String>, name: &str) -> std::io::Result<Option<Vec<u8>>> {
 | 
			
		||||
    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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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<RemoteConfig, Box<dyn
 | 
			
		||||
 | 
			
		||||
/// Core logic of the application
 | 
			
		||||
pub async fn run_app(mut args: ClientConfig) -> 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() {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								src/test/client_invalid_tls_root_certificate_file.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/test/client_invalid_tls_root_certificate_file.rs
									
									
									
									
									
										Normal file
									
								
							@@ -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();
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user