diff --git a/src/config.rs b/src/config.rs index 987db39..13741d0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,10 +2,13 @@ // Parsing the config file // +use anyhow; use std::fs; use std::sync::{Arc, Mutex}; use serde_derive::Deserialize; +use crate::types::errors::HuskError; + #[derive(Deserialize, Debug, Clone)] pub struct HuskConfig { pub connection: String, @@ -15,20 +18,18 @@ pub struct HuskConfig { impl HuskConfig { - pub fn load(path: &String) -> Option { + pub fn load(path: &String) -> anyhow::Result { match fs::read_to_string(path) { Ok(data) => { match toml::from_str(data.as_str()) { - Ok(configuration) => Some(configuration), + Ok(configuration) => Ok(configuration), Err(e) => { - eprintln!("Error while parsing config file: {:?}", e); - None + Err(HuskError::ConfigFileParseError(e.to_string()).into()) } } }, Err(e) => { - eprintln!("Error while reading config file: {:?}", e); - None + Err(HuskError::ConfigFileOpenError(e.to_string()).into()) } } } diff --git a/src/crypto.rs b/src/crypto.rs index 2d9d7f7..55e1cac 100644 --- a/src/crypto.rs +++ b/src/crypto.rs @@ -24,6 +24,8 @@ use crate::types::husk_context::HuskContext; use crate::types::introducer::Introducer; use crate::types::recipient::Recipient; +/// Returns the local trust root from the cert_store. If the trust root +/// cannot be found, it returns an error. pub fn get_local_trust_root(cert_store: &CertStore) -> anyhow::Result { let root = cert_store.certd() @@ -59,6 +61,9 @@ pub fn get_local_trust_root(cert_store: &CertStore) -> anyhow::Result { } +/// Returns all certificates with an authenticated binding to user id 'email'. +/// The certificates are not checked for usefulness (for instance, they might +/// miss an encryption subkey). pub fn get_certificates<'hc>(context: &HuskContext<'hc>, email: &str) -> Vec>> { @@ -90,6 +95,7 @@ pub fn get_certificates<'hc>(context: &HuskContext<'hc>, email: &str) result } +/// Returns all introducers available in cert_store. pub fn get_introducers<'c>(cert_store: &CertStore<'c>, policy: &StandardPolicy, local_trust_root: Fingerprint) -> Vec { let mut result = Vec::new(); @@ -130,6 +136,7 @@ pub fn get_introducers<'c>(cert_store: &CertStore<'c>, policy: &StandardPolicy, result } +/// Checks if a message contains the OpenPGP artifacts of an encrypted message. pub fn is_encrypted(body: &Bytes) -> bool { let mut ppr = match PacketParser::from_bytes(body) { @@ -158,6 +165,7 @@ pub fn is_encrypted(body: &Bytes) -> bool { false } +/// Encrypt a message for `recipients`. pub fn encrypt(context: &HuskContext<'_>, body: &Bytes, recipients: &Vec) -> anyhow::Result { diff --git a/src/main.rs b/src/main.rs index f7ad76d..4c0c09e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,13 +17,13 @@ use daemon::Daemon; async fn main() { let config_file = env::args().nth(1).expect("config file missing"); - let husk_config = HuskConfig::load(&config_file); - - if husk_config.is_none() { - eprintln!("Cannot load configuration"); - process::exit(1); - } - let husk_config = husk_config.unwrap(); + let husk_config = match HuskConfig::load(&config_file) { + Ok(config) => config, + Err(e) => { + eprintln!("{:?}", e); + process::exit(1); + } + }; log4rs::init_file(husk_config.logfile_config(), Default::default()).unwrap(); diff --git a/src/types/errors.rs b/src/types/errors.rs index 7562952..fce16a4 100644 --- a/src/types/errors.rs +++ b/src/types/errors.rs @@ -8,6 +8,10 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum HuskError { + #[error("Cannot open config file: {0}")] + ConfigFileOpenError(String), + #[error("Error while parsing config file: {0}")] + ConfigFileParseError(String), #[error("Cannot find local trust root")] NoLocalTrustRoot, #[error("Cannot access cert store")] diff --git a/src/types/introducer.rs b/src/types/introducer.rs index fe0e349..f194199 100644 --- a/src/types/introducer.rs +++ b/src/types/introducer.rs @@ -19,7 +19,7 @@ impl Introducer { pub fn can_introduce(&self, email: &str) -> bool { if let Some(regexset) = self.certification.regular_expressions() { if regexset.matches_everything() { - // return false, because unlimited certifications are + // return false, because unlimited certifications are // ignored. false } else { diff --git a/src/types/mail_context.rs b/src/types/mail_context.rs index 6586af8..d4ecf9a 100644 --- a/src/types/mail_context.rs +++ b/src/types/mail_context.rs @@ -12,8 +12,11 @@ use crate::types::recipient::Recipient; #[derive(PartialEq)] pub enum ProtectionPossibility { + // no recipient has a cert NoProtection, + // some recipients have a cert (but not all) Partial, + // all recipients have a cert Full } @@ -82,7 +85,8 @@ impl From<&MailContext<'_>> for ProtectionPossibility { (true, false) => ProtectionPossibility::Full, (true, true) => ProtectionPossibility::Partial, (false, true) => ProtectionPossibility::NoProtection, - (false, false) => ProtectionPossibility::NoProtection, // this should not occure + // (false, false) occurs if there are no recipients + (false, false) => ProtectionPossibility::NoProtection, } } } diff --git a/src/types/recipient.rs b/src/types/recipient.rs index 0c806b8..4288b27 100644 --- a/src/types/recipient.rs +++ b/src/types/recipient.rs @@ -37,10 +37,14 @@ impl TryFrom for Recipient<'_> { } impl Recipient<'_> { + /// check if this Recipient can encrypt. + // XXX: currently this check is naive pub fn can_encrypt(&self) -> bool { if self.certs.len() == 0 { return false; } + + // XXX: add check to see if a cert has encryption capable subkeys true } }