use std::borrow::Cow; use std::path::{Path, PathBuf}; use crate::command_runner::CommandRunner; use crate::command_runner::SetuidCommandRunner; use crate::symbols::dir::Dir; use crate::symbols::file::File; use crate::symbols::list::List; use crate::symbols::owner::Owner; use crate::symbols::Symbol; mod account_key; mod cert; mod chain; pub use self::account_key::AcmeAccountKey; pub use self::cert::AcmeCert; pub use self::chain::AcmeCertChain; const ROOT_CERT_FILE_NAME: &str = "lets_encrypt_x3_cross_signed.pem"; const ACCOUNT_KEY_FILE_NAME: &str = "account.key"; pub struct Factory<'a, U: AsRef, H: AsRef, C: AsRef, R: CommandRunner> { user_name: U, home_dir: H, cert: C, command_runner: &'a R, acme_command_runner: SetuidCommandRunner<'a, U, R>, } impl<'a, U: Clone + AsRef, H: AsRef, C: AsRef, R: CommandRunner> Factory<'a, U, H, C, R> { pub fn new(user_name: U, home_dir: H, cert: C, command_runner: &'a R) -> Self { let acme_command_runner = SetuidCommandRunner::new(user_name.clone(), command_runner); Self { user_name, home_dir, cert, command_runner, acme_command_runner, } } pub fn get_challenges_dir(&'a self) -> Cow { [self.home_dir.as_ref(), "challenges".as_ref()] .iter() .collect::() .into() } pub fn get_init(&'a self) -> impl Symbol + 'a { let root_cert_path: PathBuf = [self.home_dir.as_ref(), ROOT_CERT_FILE_NAME.as_ref()] .iter() .collect(); let account_key_file: PathBuf = [self.home_dir.as_ref(), ACCOUNT_KEY_FILE_NAME.as_ref()] .iter() .collect(); List::from(( AcmeAccountKey::new(account_key_file.clone(), self.command_runner), Owner::new( account_key_file, self.user_name.clone(), self.command_runner, ), Dir::new(self.get_challenges_dir()), Owner::new( self.get_challenges_dir(), self.user_name.clone(), self.command_runner, ), Dir::new("/etc/ssl/local_certs"), Owner::new( "/etc/ssl/local_certs", self.user_name.clone(), self.command_runner, ), File::new(root_cert_path, self.cert.as_ref()), )) } pub fn get_cert>(&'a self, host: HOST) -> impl Symbol + 'a { let root_cert_path: PathBuf = [self.home_dir.as_ref(), ROOT_CERT_FILE_NAME.as_ref()] .iter() .collect(); let account_key_path: PathBuf = [self.home_dir.as_ref(), ACCOUNT_KEY_FILE_NAME.as_ref()] .iter() .collect(); List::from(( AcmeCert::new( host.clone(), &self.acme_command_runner, root_cert_path.clone(), account_key_path, self.get_challenges_dir(), ), AcmeCertChain::new(host, &self.acme_command_runner, root_cert_path), )) } }