A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
2.8 KiB

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<str>, H: AsRef<Path>, C: AsRef<str>, 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<str>, H: AsRef<Path>, C: AsRef<str>, 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<'_, Path> {
[self.home_dir.as_ref(), "challenges".as_ref()]
.iter()
.collect::<PathBuf>()
.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<HOST: 'a + Clone + AsRef<str>>(&'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),
))
}
}