From d96e5c60bbf45fe0aac5c1560e7af5c255c6cf60 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Wed, 5 May 2021 11:55:52 +0800 Subject: [PATCH] feat: add --check --- src/main.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index e3615b8..47fbb34 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ use std::sync::RwLock; use std::collections::BTreeMap; use tide::Request; use std::process::exit; -use std::time::Duration; +use std::time::{Duration, SystemTime}; use async_std::task; use async_std::channel; use async_std::channel::Sender; @@ -66,6 +66,7 @@ async fn main() -> tide::Result<()> { .arg(Arg::with_name("mode").short("m").long("mode").takes_value(true).default_value("prod").help("Mode")) .arg(Arg::with_name("dir").long("dir").takes_value(true).default_value("acme_dir").help("Account key dir")) .arg(Arg::with_name("config").short("c").long("config").takes_value(true).help("Cert config")) + .arg(Arg::with_name("check").long("check").takes_value(true).help("Check cert config")) .arg(Arg::with_name("hide-logo").long("hide-logo").help("Hide logo")) .get_matches(); @@ -177,8 +178,11 @@ async fn main() -> tide::Result<()> { exit(1); }) }; + if matches.is_present("check") { + check_cert_config(&cert_config); + return Ok(()); + } let filtered_cert_config = cert_config.filter_cert_config_items(30); - for item in &filtered_cert_config.cert_items { if let (Some(common_name), Some(dns_names)) = (&item.common_name, &item.dns_names) { information!("Domains, main: {}, alt: {:?}", common_name, dns_names); @@ -205,6 +209,35 @@ async fn main() -> tide::Result<()> { Ok(()) } +fn check_cert_config(cert_config: &CertConfig) { + let secs_from_unix_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as i64; + let item_count = cert_config.cert_items.len(); + for (i, item) in cert_config.cert_items.iter().enumerate() { + information!("Checking: {}, item {} of {}", item.path, i, item_count); + let cert_fn = format!("{}/{}", item.path, CERT_NAME); + let pem = match fs::read_to_string(&cert_fn) { + Ok(pem) => pem, + Err(e) => { + warning!("Read file: {}, failed: {}", cert_fn, e); + continue; + } + }; + let x509_certificate = match x509::parse_x509(&cert_fn, &pem) { + Ok(cert) => cert, + Err(e) => { + failure!("Parse x509 file: {}, failed: {}", cert_fn, e); + continue; + } + }; + success!("Found certificate: common name: {}, dns names: {:?}, public key algo: {:?}, valid days: {}", + x509_certificate.common_name, + x509_certificate.alt_names, + x509_certificate.public_key_algo, + (x509_certificate.certificate_not_after - secs_from_unix_epoch) / (24 * 3600) + ); + } +} + fn request_acme_certificate(acme_request: AcmeRequest) -> XResult<()> { information!("Acme mode: {:?}", acme_request.mode); let url = acme_request.mode.directory_url();