diff --git a/src/certs.rs b/src/certs.rs index f5ee8a2..78c8cc5 100644 --- a/src/certs.rs +++ b/src/certs.rs @@ -20,19 +20,12 @@ where T: ICryptoProvider, { pub(crate) fn new(cfg: &AppConfig, provider: T) -> Self { - let base_dir = PathBuf::from(&cfg.base_directory); - let keys_dir = base_dir.clone().join(cfg.keys_subdir.clone()); - let name = cfg.name.clone(); - - let ca_file = keys_dir.join(cfg.ca_filename.clone()); - let key_file = keys_dir.join(format!("{}.key", &name)); - let cert_file = keys_dir.join(format!("{}.crt", &name)); let provider = Arc::new(provider); Certs { - ca_file, - key_file, - cert_file, + ca_file: cfg.ca_filepath.clone(), + key_file: cfg.key_filepath.clone(), + cert_file: cfg.cert_filepath.clone(), provider, } } diff --git a/src/common.rs b/src/common.rs index 11a4bbd..dda54a7 100644 --- a/src/common.rs +++ b/src/common.rs @@ -85,35 +85,54 @@ pub(crate) struct Args { pub(crate) struct AppConfig { pub(crate) encoding: String, pub(crate) req_days: u32, - pub(crate) keys_subdir: String, - pub(crate) config_subdir: String, - pub(crate) template_file: String, + pub(crate) template_file: PathBuf, pub(crate) openssl_default_cnf: String, pub(crate) openssl_cnf_env: String, - pub(crate) ca_filename: String, + pub(crate) ca_filepath: PathBuf, + pub(crate) ca_key_filepath: PathBuf, pub(crate) default_email_domain: String, pub(crate) openssl: OpenSSLProviderArg, - pub(crate) base_directory: String, + pub(crate) base_directory: PathBuf, pub(crate) email: String, pub(crate) name: String, + pub(crate) conf_filepath: PathBuf, + pub(crate) req_filepath: PathBuf, + pub(crate) key_filepath: PathBuf, + pub(crate) cert_filepath: PathBuf, } impl Default for AppConfig { fn default() -> Self { + let name = String::from("user"); + let base_directory: PathBuf = ".".into(); + let keys_directory = base_directory.join("keys"); + let config_directory = base_directory.join("config"); + let template_file = base_directory.join("template.ovpn"); + let openssl_default_cnf = String::from("openssl-1.0.0.cnf"); + let ca_filepath = keys_directory.join("ca.crt"); + let ca_key_filepath = keys_directory.join("ca.key"); + let req_filepath = keys_directory.join(format!("{}.csr", &name)); + let key_filepath = keys_directory.join(format!("{}.key", &name)); + let cert_filepath = keys_directory.join(format!("{}.crt", &name)); + let conf_filepath = config_directory.join(format!("{}.ovpn", &name)); + Self { encoding: DEFAULT_ENCODING.into(), req_days: 30650, - keys_subdir: "keys".into(), - config_subdir: "config".into(), - template_file: "template.ovpn".into(), - openssl_default_cnf: "openssl-1.0.0.cnf".into(), + template_file, + conf_filepath, + req_filepath, + key_filepath, + cert_filepath, + openssl_default_cnf, openssl_cnf_env: "KEY_CONFIG".into(), - ca_filename: "ca.crt".into(), + ca_filepath, + ca_key_filepath, default_email_domain: "example.com".into(), openssl: OpenSSLProviderArg::Internal, - base_directory: ".".into(), + base_directory, email: "name@example.com".into(), - name: "user".into(), + name, } } } @@ -122,11 +141,25 @@ impl From<&Args> for AppConfig { fn from(args: &Args) -> Self { let defaults = Self::default(); + let name = args.name.clone(); let base_directory = args .directory .as_ref() - .unwrap_or(&defaults.base_directory) + .map(PathBuf::from) + .unwrap_or(defaults.base_directory) .clone(); + + let keys_directory = base_directory.join(&args.keys_dir); + let config_directory = base_directory.join(&args.config_dir); + let template_file = base_directory.join(&args.template_file); + let openssl_default_cnf = String::from("openssl-1.0.0.cnf"); + let ca_filepath = keys_directory.join("ca.crt"); + let ca_key_filepath = keys_directory.join("ca.key"); + let req_filepath = keys_directory.join(format!("{}.csr", &name)); + let key_filepath = keys_directory.join(format!("{}.key", &name)); + let cert_filepath = keys_directory.join(format!("{}.crt", &name)); + let conf_filepath = config_directory.join(format!("{}.ovpn", &name)); + let email = args.email.clone().unwrap_or(format!( "{}@{}", &args.name, @@ -139,21 +172,23 @@ impl From<&Args> for AppConfig { }; let name = args.name.clone(); let openssl: OpenSSLProviderArg = args.openssl.as_ref().into(); - let template_file = args.template_file.clone(); let req_days = args.days; - let keys_subdir = args.keys_dir.clone(); - let config_subdir = args.config_dir.clone(); Self { base_directory, + template_file, + openssl_default_cnf, + ca_filepath, + ca_key_filepath, + req_filepath, + key_filepath, + cert_filepath, + conf_filepath, email, encoding, name, openssl, - template_file, req_days, - keys_subdir, - config_subdir, ..defaults } } @@ -194,7 +229,7 @@ pub(crate) async fn write_file>( let enc = encoding_from_whatwg_label(encoding).ok_or(anyhow!("encoding not found"))?; let mut bytes = Vec::new(); enc.encode_to(text, EncoderTrap::Ignore, &mut bytes) - .map_err(|_| anyhow!("can't encode"))?; + .map_err(|e| anyhow!("can't encode: {:?}", e))?; fs::write(filepath, bytes).await.context("can't write file") } diff --git a/src/main.rs b/src/main.rs index 0b52ee6..74e479f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,4 @@ -use std::path::PathBuf; - -use anyhow::{anyhow, Ok, Result}; +use anyhow::{anyhow, Result}; use clap::Parser; use common::{is_file_exist, OpenSSLProviderArg, VarsMap}; use crypto_provider::ICryptoProvider; @@ -19,10 +17,7 @@ use crate::ovpn::OvpnConfig; use crate::vars::VarsFile; async fn build_client_with(config: &AppConfig, provider: T) -> Result { - let name = config.name.clone(); - let base_dir = PathBuf::from(&config.base_directory); - let config_dir = base_dir.join(&config.config_subdir); - let config_file = config_dir.join(format!("{}.ovpn", &name)); + let config_file = config.conf_filepath.clone(); let config_file_str = config_file .to_str() .ok_or(anyhow!("config file exist err"))? @@ -62,7 +57,12 @@ async fn main() -> Result<()> { let mut vars = VarsFile::from_config(&config).await?; vars.parse().await?; - println!("found vars: {}", vars.filepath.to_str().expect("fff")); + println!( + "found vars: {}", + vars.filepath + .to_str() + .ok_or(anyhow!("vars filepath to_str"))? + ); println!("loaded: {:#?}", &vars.vars); let vars = vars.vars.ok_or(anyhow!("no vars loaded"))?; diff --git a/src/openssl/external.rs b/src/openssl/external.rs index d98056d..e6548f4 100644 --- a/src/openssl/external.rs +++ b/src/openssl/external.rs @@ -33,7 +33,6 @@ impl OpenSSLExternalProvider { pub(crate) fn from_cfg(cfg: &AppConfig, vars: VarsMap) -> Self { let base_dir = PathBuf::from(&cfg.base_directory); - let keys_dir = base_dir.join(&cfg.keys_subdir); let name = cfg.name.clone(); let mut vars = vars; @@ -41,10 +40,6 @@ impl OpenSSLExternalProvider { vars.insert("KEY_NAME".into(), name.clone()); vars.insert("KEY_EMAIL".into(), cfg.email.clone()); - let ca_file = keys_dir.join(&cfg.ca_filename); - let req_file = keys_dir.join(format!("{}.csr", &name)); - let key_file = keys_dir.join(format!("{}.key", &name)); - let cert_file = keys_dir.join(format!("{}.crt", &name)); let openssl_cnf = base_dir.join( std::env::var(&cfg.openssl_cnf_env) .as_ref() @@ -56,10 +51,10 @@ impl OpenSSLExternalProvider { base_dir, openssl_cnf, openssl: cfg.openssl.to_string(), - ca_file, - req_file, - key_file, - cert_file, + ca_file: cfg.ca_filepath.clone(), + req_file: cfg.req_filepath.clone(), + key_file: cfg.key_filepath.clone(), + cert_file: cfg.cert_filepath.clone(), req_days: cfg.req_days, } } diff --git a/src/openssl/internal.rs b/src/openssl/internal.rs index fd4eb55..0c317bb 100644 --- a/src/openssl/internal.rs +++ b/src/openssl/internal.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Context, Ok, Result}; +use anyhow::{anyhow, Context, Result}; use openssl::{ asn1::Asn1Time, conf::{Conf, ConfMethod}, @@ -93,10 +93,6 @@ fn get_time_str_x509(days: u32) -> Result { pub(crate) struct OpenSSLInternalProvider { vars: VarsMap, - #[allow(unused)] - base_dir: PathBuf, - #[allow(unused)] - openssl_cnf: PathBuf, ca_file: PathBuf, ca_key_file: PathBuf, req_file: PathBuf, @@ -121,8 +117,6 @@ impl OpenSSLInternalProvider { } pub(crate) fn try_from_cfg(cfg: &AppConfig, vars: VarsMap) -> Result { - let base_dir = PathBuf::from(&cfg.base_directory); - let keys_dir = base_dir.join(&cfg.keys_subdir); let name = cfg.name.clone(); let mut vars = vars; @@ -130,17 +124,6 @@ impl OpenSSLInternalProvider { vars.insert("KEY_NAME".into(), name.clone()); vars.insert("KEY_EMAIL".into(), cfg.email.clone()); - let ca_file = keys_dir.join(&cfg.ca_filename); - let ca_key_file = ca_file.with_extension("key"); - let req_file = keys_dir.join(format!("{}.csr", &name)); - let key_file = keys_dir.join(format!("{}.key", &name)); - let cert_file = keys_dir.join(format!("{}.crt", &name)); - let openssl_cnf = base_dir.join( - std::env::var(&cfg.openssl_cnf_env) - .as_ref() - .unwrap_or(&cfg.openssl_default_cnf), - ); - let default_key_size = "2048".to_string(); let key_size_s = vars.get("KEY_SIZE").unwrap_or(&default_key_size); let key_size: u32 = key_size_s.parse().context("parse key size error")?; @@ -149,13 +132,11 @@ impl OpenSSLInternalProvider { Ok(Self { vars, - base_dir, - openssl_cnf, - ca_file, - ca_key_file, - req_file, - key_file, - cert_file, + ca_file: cfg.ca_filepath.clone(), + ca_key_file: cfg.ca_key_filepath.clone(), + req_file: cfg.req_filepath.clone(), + key_file: cfg.key_filepath.clone(), + cert_file: cfg.cert_filepath.clone(), req_days: cfg.req_days, key_size, encoding, diff --git a/src/vars.rs b/src/vars.rs index 3874267..0cebbee 100644 --- a/src/vars.rs +++ b/src/vars.rs @@ -78,19 +78,4 @@ impl VarsFile { self.vars = Some(result); Ok(()) } - - #[allow(dead_code)] - fn apply(&self) -> Result<()> { - if let Some(vars) = self.vars.clone() { - for (key, value) in vars.iter() { - unsafe { - std::env::set_var(key, value); - } - } - } else { - Err(anyhow!("vars not parsed"))? - } - - Ok(()) - } }