From a0dc2ac9b1f0969dc5c9a4547118b32a05cf0727 Mon Sep 17 00:00:00 2001 From: Hannes de Jager Date: Fri, 16 Apr 2021 16:05:10 +0200 Subject: [PATCH] Load TLS certs only once --- src/server/datachan.rs | 11 ++++++----- src/server/ftpserver.rs | 12 ++++++++++-- src/server/tls.rs | 24 ++++++++++++++++++++---- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/server/datachan.rs b/src/server/datachan.rs index 8e7662ca..6c194203 100644 --- a/src/server/datachan.rs +++ b/src/server/datachan.rs @@ -7,7 +7,6 @@ use super::{ use crate::server::session::SharedSession; use crate::{ auth::UserDetail, - server::tls::new_config, storage::{Error, ErrorKind, Metadata, StorageBackend}, }; @@ -223,9 +222,10 @@ where async fn writer(socket: tokio::net::TcpStream, ftps_mode: FtpsConfig) -> Box { match ftps_mode { FtpsConfig::Off => Box::new(socket) as Box, - FtpsConfig::On { certs_file, key_file } => { + FtpsConfig::Building { .. } => panic!("Illegal state"), + FtpsConfig::On { tls_config } => { let io = async move { - let acceptor: TlsAcceptor = new_config(certs_file, key_file).into(); + let acceptor: TlsAcceptor = tls_config.into(); acceptor.accept(socket).await.unwrap() } .await; @@ -238,9 +238,10 @@ where async fn reader(socket: tokio::net::TcpStream, ftps_mode: FtpsConfig) -> Box { match ftps_mode { FtpsConfig::Off => Box::new(socket) as Box, - FtpsConfig::On { certs_file, key_file } => { + FtpsConfig::Building { .. } => panic!("Illegal state"), + FtpsConfig::On { tls_config } => { let io = async move { - let acceptor: TlsAcceptor = new_config(certs_file, key_file).into(); + let acceptor: TlsAcceptor = tls_config.into(); acceptor.accept(socket).await.unwrap() } .await; diff --git a/src/server/ftpserver.rs b/src/server/ftpserver.rs index 5fedc6e1..6d05fc0b 100644 --- a/src/server/ftpserver.rs +++ b/src/server/ftpserver.rs @@ -18,6 +18,7 @@ use crate::{ storage::{Metadata, StorageBackend}, }; +use crate::server::tls; use futures::{channel::mpsc::channel, SinkExt}; use options::{PassiveHost, DEFAULT_GREETING, DEFAULT_IDLE_SESSION_TIMEOUT_SECS}; use slog::*; @@ -165,7 +166,7 @@ where /// .ftps("/srv/unftp/server.certs", "/srv/unftp/server.key"); /// ``` pub fn ftps>(mut self, certs_file: P, key_file: P) -> Self { - self.ftps_mode = FtpsConfig::On { + self.ftps_mode = FtpsConfig::Building { certs_file: certs_file.into(), key_file: key_file.into(), }; @@ -371,7 +372,14 @@ where /// This function panics when called with invalid addresses or when the process is unable to /// `bind()` to the address. #[tracing_attributes::instrument] - pub async fn listen + Debug>(self, bind_address: T) -> std::result::Result<(), ServerError> { + pub async fn listen + Debug>(mut self, bind_address: T) -> std::result::Result<(), ServerError> { + self.ftps_mode = match self.ftps_mode { + FtpsConfig::Off => FtpsConfig::Off, + FtpsConfig::Building { certs_file, key_file } => FtpsConfig::On { + tls_config: tls::new_config(certs_file, key_file), + }, + FtpsConfig::On { tls_config } => FtpsConfig::On { tls_config }, + }; match self.proxy_protocol_mode { ProxyMode::On { external_control_port } => self.listen_proxy_protocol_mode(bind_address, external_control_port).await, ProxyMode::Off => self.listen_normal_mode(bind_address).await, diff --git a/src/server/tls.rs b/src/server/tls.rs index 97d52b1c..b67ca3cf 100644 --- a/src/server/tls.rs +++ b/src/server/tls.rs @@ -2,16 +2,28 @@ use rustls::{Certificate, NoClientAuth, PrivateKey}; use std::convert::TryFrom; use std::error::Error; use std::fmt; +use std::fmt::Formatter; use std::fs::File; use std::io::BufReader; use std::path::{Path, PathBuf}; use std::sync::Arc; // FTPSConfig shows how TLS security is configured for the server or a particular channel. -#[derive(Clone, Debug)] +#[derive(Clone)] pub enum FtpsConfig { Off, - On { certs_file: PathBuf, key_file: PathBuf }, + Building { certs_file: PathBuf, key_file: PathBuf }, + On { tls_config: Arc }, +} + +impl fmt::Debug for FtpsConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + FtpsConfig::Off => write!(f, "Off"), + FtpsConfig::Building { .. } => write!(f, "Building"), + FtpsConfig::On { .. } => write!(f, "On"), + } + } } #[derive(Debug, Copy, Clone)] @@ -25,17 +37,21 @@ impl fmt::Display for FtpsNotAvailable { impl Error for FtpsNotAvailable {} -// Converts +// Attempts to convert TLS configuration to an TLS Acceptor impl TryFrom for tokio_rustls::TlsAcceptor { type Error = FtpsNotAvailable; fn try_from(config: FtpsConfig) -> Result { match config { FtpsConfig::Off => Err(FtpsNotAvailable), - FtpsConfig::On { certs_file, key_file } => { + FtpsConfig::Building { certs_file, key_file } => { let acceptor: tokio_rustls::TlsAcceptor = new_config(certs_file, key_file).into(); Ok(acceptor) } + FtpsConfig::On { tls_config } => { + let acceptor: tokio_rustls::TlsAcceptor = tls_config.into(); + Ok(acceptor) + } } } }