Files
acme-client-rs/src/config.rs
2021-05-02 00:16:39 +08:00

139 lines
3.5 KiB
Rust

use serde::{Deserialize, Serialize};
use rust_util::util_file;
use rust_util::XResult;
use std::fs;
use std::fs::File;
use std::io::Read;
use acme_lib::DirectoryUrl;
const CERT_NAME: &str = "cert.pem";
const KEY_NAME: &str = "key.pem";
#[derive(Debug, Clone, Copy)]
pub enum AcmeAlgo {
Ec256,
Ec384,
Rsa(u32),
}
impl Default for AcmeAlgo {
fn default() -> Self {
Self::Ec384
}
}
impl AcmeAlgo {
pub fn parse_or_default(s: &str) -> AcmeAlgo {
Self::parse(s).unwrap_or_else(|_| Default::default())
}
pub fn parse(s: &str) -> XResult<AcmeAlgo> {
match s {
"ec256" => Ok(AcmeAlgo::Ec256),
"ec384" => Ok(AcmeAlgo::Ec384),
"rsa2048" => Ok(AcmeAlgo::Rsa(2048)),
"rsa3072" => Ok(AcmeAlgo::Rsa(3072)),
"rsa4096" => Ok(AcmeAlgo::Rsa(4096)),
_ => simple_error!("Unknown algo: {}", s),
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum AcmeMode {
Prod,
Test,
}
impl Default for AcmeMode {
fn default() -> Self {
Self::Prod
}
}
impl AcmeMode {
pub fn parse_or_default(s: &str) -> AcmeMode {
Self::parse(s).unwrap_or_else(|_| Default::default())
}
pub fn parse(s: &str) -> XResult<AcmeMode> {
match s {
"prod" => Ok(AcmeMode::Prod),
"test" => Ok(AcmeMode::Test),
_ => simple_error!("Unknown mode: {}", s),
}
}
pub fn directory_url(&self) -> DirectoryUrl {
match self {
AcmeMode::Prod => DirectoryUrl::LetsEncrypt,
AcmeMode::Test => DirectoryUrl::LetsEncryptStaging,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AcmeConfig {
pub email: String,
pub dir: String,
pub auth_timeout: Option<u64>,
pub csr_timeout: Option<u64>,
pub concurrent: Option<u32>, // ?
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CertConfigItem {
pub path: String,
pub algo: Option<String>,
pub dns_names: Option<Vec<String>>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CertConfig {
pub cert_items: Vec<CertConfigItem>,
}
impl AcmeConfig {
pub fn get_auth_timeout(&self) -> u64 {
self.auth_timeout.unwrap_or(5_000)
}
pub fn get_csr_timeout(&self) -> u64 {
self.csr_timeout.unwrap_or(5_000)
}
pub fn get_concurrent(&self) -> u32 {
self.concurrent.unwrap_or(0)
}
}
impl CertConfigItem {
pub fn fill_dns_names(&mut self) -> XResult<()> {
// TODO
Ok(())
}
}
pub fn load_acme_config(file: Option<&str>, load_default: bool) -> XResult<AcmeConfig> {
if let Some(file) = file {
let s = opt_result!(util_file::read_file_content(file), "Read file: {}, failed: {}", file);
return Ok(opt_result!(deser_hjson::from_str(&s), "Parse acme config file: {}, failed: {}", file));
}
if load_default {
let default_config = util_file::read_config(None, &[
"~/acme_config.json".to_string(),
"/etc/acme_config.json".to_string(),
]);
if let Some(default_config) = default_config {
let s = opt_result!(fs::read_to_string(default_config.clone()), "Read file: {:?}, failed: {}", default_config);
return Ok(opt_result!(deser_hjson::from_str(&s), "Parse acme config file: {:?}, failed: {}", default_config));
}
}
simple_error!("Acme config file not found!")
}