Create plugins

<!> This chapter is still incomplete.

vSMTP plugins are Rust crates compiled as dynamic libraries. 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 uses a crate called ahash used to hash types and function signatures. To hash the plugin types with the exact same hash, the plugin must use the same seed has vSMTP. 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.


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.