opensmtpd-filter-dkimout/src/main.rs

113 lines
3.1 KiB
Rust
Raw Normal View History

2023-03-26 17:15:41 +02:00
mod algorithm;
2023-03-25 19:10:06 +01:00
mod canonicalization;
2023-03-26 16:07:49 +02:00
mod config;
2023-03-19 19:06:29 +01:00
mod entry;
2023-03-19 17:13:49 +01:00
mod handshake;
2023-03-21 13:00:44 +01:00
mod logs;
2023-03-19 20:32:11 +01:00
mod message;
mod parsed_message;
2023-03-19 19:29:02 +01:00
mod stdin_reader;
2023-03-19 17:13:49 +01:00
2023-03-26 23:08:44 +02:00
use algorithm::Algorithm;
use canonicalization::CanonicalizationType;
2023-03-19 19:06:29 +01:00
use entry::Entry;
2023-03-19 20:32:11 +01:00
use message::Message;
use std::collections::HashMap;
2023-03-19 19:29:02 +01:00
use stdin_reader::StdinReader;
2023-03-19 19:06:29 +01:00
const DEFAULT_BUFF_SIZE: usize = 1024;
2023-03-26 23:08:44 +02:00
const DEFAULT_CNF_ALGORITHM: Algorithm = Algorithm::Rsa2048Sha256;
const DEFAULT_CNF_CANONICALIZATION_BODY: CanonicalizationType = CanonicalizationType::Relaxed;
const DEFAULT_CNF_CANONICALIZATION_HEADER: CanonicalizationType = CanonicalizationType::Relaxed;
const DEFAULT_CNF_CRYPTOPERIOD: u64 = 15552000;
const DEFAULT_CNF_EXPIRATION: u64 = 1296000;
const DEFAULT_CNF_HEADERS: &str = "from:reply-to:subject:date:to:cc";
const DEFAULT_CNF_HEADERS_OPT: &str = "resent-date:resent-from:resent-to:resent-cc:in-reply-to:references:list-id:list-help:list-unsubscribe:list-subscribe:list-post:list-owner:list-archive";
const DEFAULT_CNF_KEY_DB: &str = "key-db.sqlite3";
const DEFAULT_CNF_REVOCATION: u64 = 1728000;
2023-03-26 23:42:16 +02:00
const DEFAULT_LIB_DIR: &str = env!("VARLIBDIR");
2023-03-23 20:54:20 +01:00
const DEFAULT_MSG_SIZE: usize = 1024 * 1024;
2023-03-21 13:00:44 +01:00
const LOG_LEVEL_ENV_VAR: &str = "OPENSMTPD_FILTER_DKIMOUT_LOG_LEVEL";
#[macro_export]
macro_rules! display_bytes {
($bytes: expr) => {
$bytes
.iter()
.map(|b| {
let v: Vec<u8> = std::ascii::escape_default(*b).collect();
String::from_utf8_lossy(&v).to_string()
})
.collect::<String>()
};
}
macro_rules! log_messages {
($list: ident) => {
log::trace!(
"message list has {} elements: {}",
$list.len(),
$list
.iter()
.map(|(k, v)| { format!("{k} ({} lines)", v.nb_lines()) })
.collect::<Vec<String>>()
.join(", ")
)
};
}
2023-03-19 19:06:29 +01:00
2023-04-09 11:07:16 +02:00
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
2023-03-26 16:07:49 +02:00
match config::Config::init() {
Ok(cnf) => {
2023-03-26 21:49:34 +02:00
logs::init_log_system(&cnf);
2023-03-26 16:07:49 +02:00
log::debug!("{cnf:?}");
2023-04-09 11:07:16 +02:00
main_loop(&cnf).await
2023-03-26 16:07:49 +02:00
}
2023-03-26 21:49:34 +02:00
Err(e) => eprintln!("{e}"),
2023-03-26 16:07:49 +02:00
}
2023-04-09 11:07:16 +02:00
Ok(())
2023-03-26 16:07:49 +02:00
}
2023-04-09 11:07:16 +02:00
async fn main_loop(cnf: &config::Config) {
2023-03-19 19:29:02 +01:00
let mut reader = StdinReader::new();
2023-03-19 20:32:11 +01:00
let mut messages: HashMap<String, Message> = HashMap::new();
2023-04-09 11:07:16 +02:00
handshake::read_config(&mut reader).await;
2023-03-19 17:13:49 +01:00
handshake::register_filter();
2023-03-21 13:00:44 +01:00
log_messages!(messages);
2023-03-19 19:06:29 +01:00
loop {
2023-04-09 11:07:16 +02:00
match Entry::from_bytes(&reader.read_line().await) {
2023-03-19 19:06:29 +01:00
Ok(entry) => {
2023-03-19 20:32:11 +01:00
let msg_id = entry.get_msg_id();
match messages.get_mut(&msg_id) {
Some(msg) => {
if !entry.is_end_of_message() {
2023-03-21 13:00:44 +01:00
log::debug!("new line in message: {msg_id}");
2023-03-19 20:32:11 +01:00
msg.append_line(entry.get_data());
} else {
2023-03-21 13:00:44 +01:00
log::debug!("message ready: {msg_id}");
2023-04-09 11:07:16 +02:00
msg.sign_and_return(&cnf).await;
2023-03-19 20:32:11 +01:00
messages.remove(&msg_id);
2023-03-21 13:00:44 +01:00
log::debug!("message removed: {msg_id}");
2023-03-19 20:32:11 +01:00
}
}
None => {
2023-03-19 21:42:36 +01:00
let msg = Message::from_entry(&entry);
2023-03-19 20:32:11 +01:00
if !entry.is_end_of_message() {
2023-03-21 13:00:44 +01:00
log::debug!("new message: {msg_id}");
2023-03-19 20:32:11 +01:00
messages.insert(msg_id, msg);
} else {
2023-03-21 13:00:44 +01:00
log::debug!("empty new message: {msg_id}");
2023-04-09 11:07:16 +02:00
msg.sign_and_return(&cnf).await;
2023-03-19 20:32:11 +01:00
}
}
2023-03-19 19:06:29 +01:00
}
}
Err(err) => {
2023-03-21 13:00:44 +01:00
log::error!("invalid filter line: {err}");
2023-03-19 19:06:29 +01:00
}
}
2023-03-21 13:00:44 +01:00
log_messages!(messages);
2023-03-19 19:06:29 +01:00
}
}