/* * Copyright (c) 2023 Stalwart Labs Ltd. * * This file is part of Stalwart Mail Server. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * in the LICENSE file at the top-level directory of this distribution. * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * * You can be released from the requirements of the AGPLv3 license by * purchasing a commercial license. Please contact licensing@stalw.art * for more details. */ pub mod bayes; pub mod dns; pub mod exec; pub mod http; pub mod lookup; pub mod query; use mail_parser::Message; use sieve::{runtime::Variable, FunctionMap, Input}; use tokio::runtime::Handle; use crate::{config::scripts::SieveContext, core::SMTP}; type RegisterPluginFnc = fn(u32, &mut FunctionMap) -> (); type ExecPluginFnc = fn(PluginContext<'_>) -> Variable; pub struct PluginContext<'x> { pub span: &'x tracing::Span, pub handle: &'x Handle, pub core: &'x SMTP, pub message: &'x Message<'x>, pub arguments: Vec, } const PLUGINS_EXEC: [ExecPluginFnc; 11] = [ query::exec, exec::exec, lookup::exec, lookup::exec_map, lookup::exec_map_many, dns::exec, dns::exec_exists, http::exec_header, bayes::exec_train, bayes::exec_untrain, bayes::exec_classify, ]; const PLUGINS_REGISTER: [RegisterPluginFnc; 11] = [ query::register, exec::register, lookup::register, lookup::register_map, lookup::register_map_many, dns::register, dns::register_exists, http::register_header, bayes::register_train, bayes::register_untrain, bayes::register_classify, ]; pub trait RegisterSievePlugins { fn register_plugins(self) -> Self; } impl RegisterSievePlugins for FunctionMap { fn register_plugins(mut self) -> Self { #[cfg(feature = "test_mode")] { self.set_external_function("print", PLUGINS_EXEC.len() as u32, 1) } for (i, fnc) in PLUGINS_REGISTER.iter().enumerate() { fnc(i as u32, &mut self); } self } } impl SMTP { pub fn run_plugin_blocking(&self, id: u32, ctx: PluginContext<'_>) -> Input { #[cfg(feature = "test_mode")] if id == PLUGINS_EXEC.len() as u32 { return test_print(ctx); } PLUGINS_EXEC .get(id as usize) .map(|fnc| fnc(ctx)) .unwrap_or_default() .into() } } #[cfg(feature = "test_mode")] pub fn test_print(ctx: PluginContext<'_>) -> Input { println!("{}", ctx.arguments[0].to_string()); Input::True }