Create plugins
🚧 This chapter is still incomplete.
vSMTP plugins are Rust crates compiled as dynamic libraries that extends vSMTP base features.
They can be imported directly in filtering scripts.
Requirements
- First, make sure that Rust and Cargo are installed on the system.
- The Rust community as created a cargo command called Cargo generate which is used to fetch Rust project templates from Github. Make sure to install it too.
- Rhai imports a crate called ahash to hash types and function signatures to look them up at runtime. Therefore, plugin functions signatures must be hashed with the exact same seed than the core of vSMTP, so that Rhai can call the right functions. See the
rhai-dylib
crate for more details.
Get the plugin template
A Rhai dylib template is available to easily create plugins.
cargo generate --git https://github.com/ltabis/rhai-dylib-template.git
🤷 Project Name : vsmtp-plugin-awesome
🔧 Destination: /path/vsmtp-plugin-awesome ...
🔧 Generating template ...
🤷 What is the ahash key of program that will load this module ? [default: [1, 2, 3, 4]]: [1, 2, 3, 4]
[1/7] Done: .cargo/config.toml
[2/7] Skipped: .cargo
[3/7] Done: .gitignore
[4/7] Done: Cargo.toml
[5/7] Done: README.md
[6/7] Done: src/lib.rs
[7/7] Skipped: src
🔧 Moving generated files into: `/path/vsmtp-plugin-awesome`...
💡 Initializing a fresh Git repository
✨ Done! New project created /path/vsmtp-plugin-awesome
cargo generate
will prompt for a project name (It is recommended to use the vsmtp-plugin-*
nomenclature to name vSMTP plugins) and a ahash seed. (To get more detail on what are ahash seeds and what they are used for, check out the rhai-dylib
crate)
Overview
#![allow(unused)] fn main() { use rhai::plugin::*; #[export_module] mod vsmtp_plugin_awesome { // Build the module here. } /// Export the vsmtp_plugin_awesome module. #[no_mangle] pub extern "C" fn module_entrypoint() -> rhai::Shared<rhai::Module> { // The seed must be the same as the one used in the program that will // load this module. rhai::config::hashing::set_ahash_seed(Some([1, 2, 3, 4])).unwrap(); rhai::exported_module!(vsmtp_plugin_awesome).into() } }
Generated Rust code using `cargo generate`, in vsmtp-plugin-awesome/src/lib.rs
cargo generate
created a basic Rust project called vsmtp-plugin-awesome
. It contains a module_entrypoint
function that returns a Rhai module. Once this plugin is imported in vSMTP via the Rhai import
statement, the
module_entrypoint
function is called and the returned Rhai module is used to extend .vsl
scripts.
The
module_entrypoint
function must be present in the crate, otherwise vSMTP will not run the plugin.
[package]
name = "vsmtp_plugin_awesome"
version = "0.1.0"
edition = "2021"
authors = ["user <user@example.com>"]
[lib]
crate-type = ["cdylib"]
[dependencies]
rhai = { version = "1.11" }
Generated Cargo.toml file
Has specified in the manifest file generated for the project, the configured crate type is cdylib
.
crate-type = ["cdylib"]
With this option, the crate can be compiled into a dynamic library, and vSMTP can access the plugin via the module_entrypoint
function at runtime.