From 3cbbd72a1447c6eba1c43a3f47acc4ea49059237 Mon Sep 17 00:00:00 2001 From: Pierre Hubert Date: Wed, 31 Aug 2022 14:36:07 +0200 Subject: [PATCH] cargo fmt --- base/src/lib.rs | 2 +- tcp_relay_client/src/client_config.rs | 40 +++++++------ tcp_relay_client/src/lib.rs | 2 +- tcp_relay_client/src/main.rs | 35 ++++++++---- tcp_relay_client/src/relay_client.rs | 45 ++++++++------- tcp_relay_server/src/lib.rs | 4 +- tcp_relay_server/src/main.rs | 45 +++++++++------ tcp_relay_server/src/relay_ws.rs | 56 +++++++++++++------ tcp_relay_server/src/server_config.rs | 10 +++- .../src/tls_cert_client_verifier.rs | 30 +++++++--- 10 files changed, 170 insertions(+), 99 deletions(-) diff --git a/base/src/lib.rs b/base/src/lib.rs index a128119..6a5a62a 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -4,4 +4,4 @@ pub struct RelayedPort { pub port: u16, } -pub type RemoteConfig = Vec; \ No newline at end of file +pub type RemoteConfig = Vec; diff --git a/tcp_relay_client/src/client_config.rs b/tcp_relay_client/src/client_config.rs index 7809a75..5616fc7 100644 --- a/tcp_relay_client/src/client_config.rs +++ b/tcp_relay_client/src/client_config.rs @@ -42,17 +42,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._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_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._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 @@ -69,18 +72,19 @@ impl ClientConfig { pub fn get_client_keypair(&self) -> Option<(&Vec, &Vec)> { if let (Some(cert), Some(key)) = (&self._tls_cert_cache, &self._tls_key_cache) { Some((cert, key)) - } else { None } + } else { + None + } } /// Get client certificate & key pair, in a single memory buffer pub fn get_merged_client_keypair(&self) -> Option> { - self.get_client_keypair() - .map(|(c, k)| { - let mut out = k.to_vec(); - out.put_slice("\n".as_bytes()); - out.put_slice(c); - out - }) + self.get_client_keypair().map(|(c, k)| { + let mut out = k.to_vec(); + out.put_slice("\n".as_bytes()); + out.put_slice(c); + out + }) } } @@ -93,4 +97,4 @@ mod test { use clap::CommandFactory; ClientConfig::command().debug_assert() } -} \ No newline at end of file +} diff --git a/tcp_relay_client/src/lib.rs b/tcp_relay_client/src/lib.rs index 2efbe10..fdbdcbc 100644 --- a/tcp_relay_client/src/lib.rs +++ b/tcp_relay_client/src/lib.rs @@ -1,2 +1,2 @@ pub mod client_config; -pub mod relay_client; \ No newline at end of file +pub mod relay_client; diff --git a/tcp_relay_client/src/main.rs b/tcp_relay_client/src/main.rs index 5be6308..2df316e 100644 --- a/tcp_relay_client/src/main.rs +++ b/tcp_relay_client/src/main.rs @@ -24,20 +24,25 @@ async fn get_server_config(config: &ClientConfig) -> Result Result<(), Box> { // 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!"); + log::error!( + "If you specify one of TLS certificate / key, you must then specify the other!" + ); panic!(); } @@ -71,9 +78,13 @@ async fn main() -> Result<(), Box> { let listen_address = format!("{}:{}", args.listen_address, port.port); let h = tokio::spawn(relay_client( - format!("{}/ws?id={}&token={}", - args.relay_url, port.id, urlencoding::encode(args.get_auth_token())) - .replace("http", "ws"), + format!( + "{}/ws?id={}&token={}", + args.relay_url, + port.id, + urlencoding::encode(args.get_auth_token()) + ) + .replace("http", "ws"), listen_address, args.clone(), )); @@ -83,4 +94,4 @@ async fn main() -> Result<(), Box> { join_all(handles).await; Ok(()) -} \ No newline at end of file +} diff --git a/tcp_relay_client/src/relay_client.rs b/tcp_relay_client/src/relay_client.rs index e861216..33277f4 100644 --- a/tcp_relay_client/src/relay_client.rs +++ b/tcp_relay_client/src/relay_client.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use futures::{SinkExt, StreamExt}; use hyper_rustls::ConfigBuilderExt; use rustls::{Certificate, PrivateKey, RootCertStore}; -use rustls_pemfile::{Item, read_one}; +use rustls_pemfile::{read_one, Item}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; use tokio_tungstenite::tungstenite::Message; @@ -22,7 +22,9 @@ pub async fn relay_client(ws_url: String, listen_address: String, config: Arc config.with_native_roots(), @@ -65,7 +66,8 @@ async fn relay_connection(ws_url: String, socket: TcpStream, conf: Arc>(); let key = match read_one(&mut Cursor::new(key)) - .expect("Failed to read client private key!") { + .expect("Failed to read client private key!") + { None => { log::error!("Failed to extract private key!"); panic!(); @@ -78,30 +80,29 @@ async fn relay_connection(ws_url: String, socket: TcpStream, conf: Arc WS write let future = async move { @@ -136,12 +137,18 @@ async fn relay_connection(ws_url: String, socket: TcpStream, conf: Arc { - log::error!("Failed to read from WebSocket. Breaking read loop... {:?}", e); + log::error!( + "Failed to read from WebSocket. Breaking read loop... {:?}", + e + ); break; } Ok(Message::Binary(b)) => { if let Err(e) = tcp_write.write_all(&b).await { - log::error!("Failed to forward message to websocket. Closing reading end... {:?}", e); + log::error!( + "Failed to forward message to websocket. Closing reading end... {:?}", + e + ); break; }; } @@ -149,7 +156,7 @@ async fn relay_connection(ws_url: String, socket: TcpStream, conf: Arc log::info!("{:?}", m) + Ok(m) => log::info!("{:?}", m), } } -} \ No newline at end of file +} diff --git a/tcp_relay_server/src/lib.rs b/tcp_relay_server/src/lib.rs index 44db330..a042584 100644 --- a/tcp_relay_server/src/lib.rs +++ b/tcp_relay_server/src/lib.rs @@ -1,3 +1,3 @@ -pub mod server_config; pub mod relay_ws; -pub mod tls_cert_client_verifier; \ No newline at end of file +pub mod server_config; +pub mod tls_cert_client_verifier; diff --git a/tcp_relay_server/src/main.rs b/tcp_relay_server/src/main.rs index 9622947..4f448c1 100644 --- a/tcp_relay_server/src/main.rs +++ b/tcp_relay_server/src/main.rs @@ -2,11 +2,11 @@ use std::fs::File; use std::io::BufReader; use std::sync::Arc; -use actix_web::{App, HttpRequest, HttpResponse, HttpServer, middleware, Responder, web}; use actix_web::web::Data; +use actix_web::{middleware, web, App, HttpRequest, HttpResponse, HttpServer, Responder}; use clap::Parser; use rustls::{Certificate, PrivateKey}; -use rustls_pemfile::{certs, Item, read_one}; +use rustls_pemfile::{certs, read_one, Item}; use base::RelayedPort; use tcp_relay_server::relay_ws::relay_ws; @@ -19,7 +19,9 @@ pub async fn hello_route() -> &'static str { pub async fn config_route(req: HttpRequest, data: Data>) -> impl Responder { if data.has_token_auth() { - let token = req.headers().get("Authorization") + let token = req + .headers() + .get("Authorization") .map(|t| t.to_str().unwrap_or_default()) .unwrap_or_default() .strip_prefix("Bearer ") @@ -31,10 +33,14 @@ pub async fn config_route(req: HttpRequest, data: Data>) -> im } HttpResponse::Ok().json( - data.ports.iter() + data.ports + .iter() .enumerate() - .map(|(id, port)| RelayedPort { id, port: port + data.increment_ports }) - .collect::>() + .map(|(id, port)| RelayedPort { + id, + port: port + data.increment_ports, + }) + .collect::>(), ) } @@ -73,13 +79,13 @@ async fn main() -> 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 = &mut BufReader::new(File::open(cert).unwrap()); let key_file = &mut BufReader::new(File::open(key).unwrap()); // Get certificates chain - let cert_chain = certs(cert_file).unwrap() + let cert_chain = certs(cert_file) + .unwrap() .into_iter() .map(Certificate) .collect(); @@ -98,20 +104,22 @@ async fn main() -> std::io::Result<()> { } }; - let config = rustls::ServerConfig::builder() - .with_safe_defaults(); + let config = rustls::ServerConfig::builder().with_safe_defaults(); let config = match args.has_tls_client_auth() { - true => config.with_client_cert_verifier( - Arc::new(CustomCertClientVerifier::new(args.clone()))), - false => config.with_no_client_auth() + true => config + .with_client_cert_verifier(Arc::new(CustomCertClientVerifier::new(args.clone()))), + false => config.with_no_client_auth(), }; - let config = config.with_single_cert(cert_chain, PrivateKey(key)) + let config = config + .with_single_cert(cert_chain, PrivateKey(key)) .expect("Failed to load TLS certificate!"); Some(config) - } else { None }; + } else { + None + }; log::info!("Starting relay on http://{}", args.listen_address); @@ -129,6 +137,7 @@ async fn main() -> std::io::Result<()> { server.bind_rustls(&args.listen_address, tls_conf)? } else { server.bind(&args.listen_address)? - }.run() - .await -} \ No newline at end of file + } + .run() + .await +} diff --git a/tcp_relay_server/src/relay_ws.rs b/tcp_relay_server/src/relay_ws.rs index 3d2c57c..56a4707 100644 --- a/tcp_relay_server/src/relay_ws.rs +++ b/tcp_relay_server/src/relay_ws.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use actix::{Actor, ActorContext, AsyncContext, Handler, Message, StreamHandler}; -use actix_web::{Error, HttpRequest, HttpResponse, web}; +use actix_web::{web, Error, HttpRequest, HttpResponse}; use actix_web_actors::ws; use actix_web_actors::ws::{CloseCode, CloseReason}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; @@ -32,7 +32,6 @@ struct RelayWS { // Client must respond to ping at a specific interval, otherwise we drop connection hb: Instant, - // TODO : handle socket close } @@ -109,7 +108,9 @@ impl StreamHandler> for RelayWS { Ok(ws::Message::Text(text)) => ctx.text(text), Ok(ws::Message::Close(_reason)) => ctx.stop(), Ok(ws::Message::Binary(data)) => { - if let Err(e) = futures::executor::block_on(self.tcp_write.write_all(&data.to_vec())) { + if let Err(e) = + futures::executor::block_on(self.tcp_write.write_all(&data.to_vec())) + { log::error!("Failed to forward some data, closing connection! {:?}", e); ctx.stop(); } @@ -150,17 +151,30 @@ pub struct WebSocketQuery { token: Option, } -pub async fn relay_ws(req: HttpRequest, stream: web::Payload, - query: web::Query, - conf: web::Data>) -> Result { - if conf.has_token_auth() && - !conf.tokens.iter().any(|t| t == query.token.as_deref().unwrap_or_default()) { - log::error!("Rejected WS request from {:?} due to invalid token!", req.peer_addr()); +pub async fn relay_ws( + req: HttpRequest, + stream: web::Payload, + query: web::Query, + conf: web::Data>, +) -> Result { + if conf.has_token_auth() + && !conf + .tokens + .iter() + .any(|t| t == query.token.as_deref().unwrap_or_default()) + { + log::error!( + "Rejected WS request from {:?} due to invalid token!", + req.peer_addr() + ); return Ok(HttpResponse::Unauthorized().json("Invalid / missing token!")); } if conf.ports.len() <= query.id { - log::error!("Rejected WS request from {:?} due to invalid port number!", req.peer_addr()); + log::error!( + "Rejected WS request from {:?} due to invalid port number!", + req.peer_addr() + ); return Ok(HttpResponse::BadRequest().json("Invalid port number!")); } @@ -169,14 +183,24 @@ pub async fn relay_ws(req: HttpRequest, stream: web::Payload, let (tcp_read, tcp_write) = match TcpStream::connect(&upstream_addr).await { Ok(s) => s.into_split(), Err(e) => { - log::error!("Failed to establish connection with upstream server! {:?}", e); - return Ok(HttpResponse::InternalServerError() - .json("Failed to establish connection!")); + log::error!( + "Failed to establish connection with upstream server! {:?}", + e + ); + return Ok(HttpResponse::InternalServerError().json("Failed to establish connection!")); } }; - let relay = RelayWS { tcp_read: Some(tcp_read), tcp_write, hb: Instant::now() }; + let relay = RelayWS { + tcp_read: Some(tcp_read), + tcp_write, + hb: Instant::now(), + }; let resp = ws::start(relay, &req, stream); - log::info!("Opening new WS connection for {:?} to {}", req.peer_addr(), upstream_addr); + log::info!( + "Opening new WS connection for {:?} to {}", + req.peer_addr(), + upstream_addr + ); resp -} \ No newline at end of file +} diff --git a/tcp_relay_server/src/server_config.rs b/tcp_relay_server/src/server_config.rs index f235920..3c6c68e 100644 --- a/tcp_relay_server/src/server_config.rs +++ b/tcp_relay_server/src/server_config.rs @@ -2,8 +2,12 @@ use clap::Parser; /// TCP relay server #[derive(Parser, Debug, Clone)] -#[clap(author, version, about, -long_about = "TCP-over-HTTP server. This program might be configured behind a reverse-proxy.")] +#[clap( + author, + version, + about, + long_about = "TCP-over-HTTP server. This program might be configured behind a reverse-proxy." +)] pub struct ServerConfig { /// Access tokens #[clap(short, long)] @@ -62,4 +66,4 @@ impl ServerConfig { pub fn has_auth(&self) -> bool { self.has_token_auth() || self.has_tls_client_auth() } -} \ No newline at end of file +} diff --git a/tcp_relay_server/src/tls_cert_client_verifier.rs b/tcp_relay_server/src/tls_cert_client_verifier.rs index a025775..97be55c 100644 --- a/tcp_relay_server/src/tls_cert_client_verifier.rs +++ b/tcp_relay_server/src/tls_cert_client_verifier.rs @@ -3,8 +3,8 @@ use std::io::BufReader; use std::sync::Arc; use std::time::SystemTime; -use rustls::{Certificate, DistinguishedNames, Error, RootCertStore}; use rustls::server::{AllowAnyAuthenticatedClient, ClientCertVerified, ClientCertVerifier}; +use rustls::{Certificate, DistinguishedNames, Error, RootCertStore}; use rustls_pemfile::certs; use crate::server_config::ServerConfig; @@ -15,12 +15,17 @@ pub struct CustomCertClientVerifier { impl CustomCertClientVerifier { pub fn new(conf: Arc) -> Self { - let cert_path = conf.tls_client_auth_root_cert.as_deref() + let cert_path = conf + .tls_client_auth_root_cert + .as_deref() .expect("No root certificates for client authentication provided!"); - let cert_file = &mut BufReader::new(File::open(cert_path) - .expect("Failed to read root certificates for client authentication!")); + let cert_file = &mut BufReader::new( + File::open(cert_path) + .expect("Failed to read root certificates for client authentication!"), + ); - let root_certs = certs(cert_file).unwrap() + let root_certs = certs(cert_file) + .unwrap() .into_iter() .map(Certificate) .collect::>(); @@ -32,7 +37,9 @@ impl CustomCertClientVerifier { let mut store = RootCertStore::empty(); for cert in root_certs { - store.add(&cert).expect("Failed to add certificate to root store"); + store + .add(&cert) + .expect("Failed to add certificate to root store"); } Self { @@ -54,8 +61,13 @@ impl ClientCertVerifier for CustomCertClientVerifier { Some(vec![]) } - fn verify_client_cert(&self, end_entity: &Certificate, intermediates: &[Certificate], now: SystemTime) -> Result { - self.upstream_cert_verifier.verify_client_cert(end_entity, intermediates, now) + fn verify_client_cert( + &self, + end_entity: &Certificate, + intermediates: &[Certificate], + now: SystemTime, + ) -> Result { + self.upstream_cert_verifier + .verify_client_cert(end_entity, intermediates, now) } } -