Add a minimal documentation
This commit is contained in:
parent
dafea54dbb
commit
386d4f3446
3 changed files with 228 additions and 153 deletions
23
README.md
23
README.md
|
@ -1,16 +1,19 @@
|
||||||
# Rust-OpenSMTPD
|
# Rust-OpenSMTPD
|
||||||
|
|
||||||
Rust binding for [OpenSMTPD] filters.
|
[![Build Status](https://api.travis-ci.org/breard-r/rust-opensmtpd.svg?branch=master)](https://travis-ci.org/breard-r/rust-opensmtpd)
|
||||||
|
[![Rust-OpenSMTPD on crates.io](https://img.shields.io/crates/v/opensmtpd.svg)](https://crates.io/crates/opensmtpd)
|
||||||
|
[![Rust-OpenSMTPD on docs.rs](https://docs.rs/opensmtpd/badge.svg)](https://docs.rs/opensmtpd/)
|
||||||
|
![License: MIT or Apache-2.0](https://img.shields.io/crates/l/opensmtpd)
|
||||||
|
|
||||||
|
|
||||||
# Features
|
Rust binding for [OpenSMTPD](https://www.opensmtpd.org/) filters.
|
||||||
|
|
||||||
This is a work in progress, the API is **not** stabilized yet.
|
|
||||||
|
|
||||||
- [x] Reports
|
|
||||||
- [ ] Filters
|
|
||||||
- [x] Filter-level context
|
|
||||||
- [x] Session-level context
|
|
||||||
|
|
||||||
|
|
||||||
[OpenSMTPD]: https://www.opensmtpd.org/
|
# Documentation
|
||||||
|
|
||||||
|
Read the documentation on [docs.rs](https://docs.rs/opensmtpd/).
|
||||||
|
|
||||||
|
|
||||||
|
# Requirements
|
||||||
|
|
||||||
|
Rust 1.41 or newer.
|
||||||
|
|
314
src/filter.rs
314
src/filter.rs
|
@ -4,152 +4,10 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Filter {
|
pub trait Filter {
|
||||||
fn on_report_link_auth(&mut self, _entry: &ReportEntry, _username: &str, _result: AuthResult) {}
|
|
||||||
fn has_report_link_auth(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_link_connect(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_rdns: &str,
|
|
||||||
_fcrdns: &str,
|
|
||||||
_src: &Address,
|
|
||||||
_dest: &Address,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_link_connect(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_link_disconnect(&mut self, _entry: &ReportEntry) {}
|
|
||||||
fn has_report_link_disconnect(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_link_greeting(&mut self, _entry: &ReportEntry, _hostname: &str) {}
|
|
||||||
fn has_report_link_greeting(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_link_identify(&mut self, _entry: &ReportEntry, _method: Method, _identity: &str) {}
|
|
||||||
fn has_report_link_identify(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_link_tls(&mut self, _entry: &ReportEntry, _tls_string: &str) {}
|
|
||||||
fn has_report_link_tls(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_begin(&mut self, _entry: &ReportEntry, _message_id: &str) {}
|
|
||||||
fn has_report_tx_begin(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_mail(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_message_id: &str,
|
|
||||||
_result: MailResult,
|
|
||||||
_address: &str,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_tx_mail(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_reset(&mut self, _entry: &ReportEntry, _message_id: &Option<String>) {}
|
|
||||||
fn has_report_tx_reset(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_rcpt(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_message_id: &str,
|
|
||||||
_result: MailResult,
|
|
||||||
_address: &str,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_tx_rcpt(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_envelope(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_message_id: &str,
|
|
||||||
_envelope_id: &str,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_tx_envelope(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_data(&mut self, _entry: &ReportEntry, _message_id: &str, _result: MailResult) {}
|
|
||||||
fn has_report_tx_data(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_commit(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_message_id: &str,
|
|
||||||
_message_size: usize,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_tx_commit(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_tx_rollback(&mut self, _entry: &ReportEntry, _message_id: &str) {}
|
|
||||||
fn has_report_tx_rollback(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_protocol_client(&mut self, _entry: &ReportEntry, _command: &str) {}
|
|
||||||
fn has_report_protocol_client(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_protocol_server(&mut self, _entry: &ReportEntry, _response: &str) {}
|
|
||||||
fn has_report_protocol_server(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_filter_response(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_phase: FilterPhase,
|
|
||||||
_response: &str,
|
|
||||||
_param: &Option<String>,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_filter_response(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_filter_report(
|
|
||||||
&mut self,
|
|
||||||
_entry: &ReportEntry,
|
|
||||||
_filter_kind: FilterKind,
|
|
||||||
_name: &str,
|
|
||||||
_message: &str,
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
fn has_report_filter_report(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_report_timeout(&mut self, _entry: &ReportEntry) {}
|
|
||||||
fn has_report_timeout(&self) -> bool {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_filter_auth(&mut self, _entry: &FilterEntry, _auth: &str) -> FilterResponse {
|
fn on_filter_auth(&mut self, _entry: &FilterEntry, _auth: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_auth(&self) -> bool {
|
fn has_filter_auth(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -157,6 +15,7 @@ pub trait Filter {
|
||||||
fn on_filter_commit(&mut self, _entry: &FilterEntry) -> FilterResponse {
|
fn on_filter_commit(&mut self, _entry: &FilterEntry) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_commit(&self) -> bool {
|
fn has_filter_commit(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -171,6 +30,7 @@ pub trait Filter {
|
||||||
) -> FilterResponse {
|
) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_connect(&self) -> bool {
|
fn has_filter_connect(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -178,6 +38,7 @@ pub trait Filter {
|
||||||
fn on_filter_data(&mut self, _entry: &FilterEntry) -> FilterResponse {
|
fn on_filter_data(&mut self, _entry: &FilterEntry) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_data(&self) -> bool {
|
fn has_filter_data(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +46,7 @@ pub trait Filter {
|
||||||
fn on_filter_ehlo(&mut self, _entry: &FilterEntry, _identity: &str) -> FilterResponse {
|
fn on_filter_ehlo(&mut self, _entry: &FilterEntry, _identity: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_ehlo(&self) -> bool {
|
fn has_filter_ehlo(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -192,6 +54,7 @@ pub trait Filter {
|
||||||
fn on_filter_helo(&mut self, _entry: &FilterEntry, _identity: &str) -> FilterResponse {
|
fn on_filter_helo(&mut self, _entry: &FilterEntry, _identity: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_helo(&self) -> bool {
|
fn has_filter_helo(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -199,6 +62,7 @@ pub trait Filter {
|
||||||
fn on_filter_mail_from(&mut self, _entry: &FilterEntry, _address: &str) -> FilterResponse {
|
fn on_filter_mail_from(&mut self, _entry: &FilterEntry, _address: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_mail_from(&self) -> bool {
|
fn has_filter_mail_from(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -206,6 +70,7 @@ pub trait Filter {
|
||||||
fn on_filter_rcpt_to(&mut self, _entry: &FilterEntry, _address: &str) -> FilterResponse {
|
fn on_filter_rcpt_to(&mut self, _entry: &FilterEntry, _address: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_rcpt_to(&self) -> bool {
|
fn has_filter_rcpt_to(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +78,170 @@ pub trait Filter {
|
||||||
fn on_filter_starttls(&mut self, _entry: &FilterEntry, _tls_string: &str) -> FilterResponse {
|
fn on_filter_starttls(&mut self, _entry: &FilterEntry, _tls_string: &str) -> FilterResponse {
|
||||||
FilterResponse::Proceed
|
FilterResponse::Proceed
|
||||||
}
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
fn has_filter_starttls(&self) -> bool {
|
fn has_filter_starttls(&self) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_report_link_auth(&mut self, _entry: &ReportEntry, _username: &str, _result: AuthResult) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_link_auth(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_link_connect(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_rdns: &str,
|
||||||
|
_fcrdns: &str,
|
||||||
|
_src: &Address,
|
||||||
|
_dest: &Address,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_link_connect(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_link_disconnect(&mut self, _entry: &ReportEntry) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_link_disconnect(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_link_greeting(&mut self, _entry: &ReportEntry, _hostname: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_link_greeting(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_link_identify(&mut self, _entry: &ReportEntry, _method: Method, _identity: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_link_identify(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_link_tls(&mut self, _entry: &ReportEntry, _tls_string: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_link_tls(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_begin(&mut self, _entry: &ReportEntry, _message_id: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_begin(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_mail(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_message_id: &str,
|
||||||
|
_result: MailResult,
|
||||||
|
_address: &str,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_mail(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_reset(&mut self, _entry: &ReportEntry, _message_id: &Option<String>) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_reset(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_rcpt(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_message_id: &str,
|
||||||
|
_result: MailResult,
|
||||||
|
_address: &str,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_rcpt(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_envelope(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_message_id: &str,
|
||||||
|
_envelope_id: &str,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_envelope(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_data(&mut self, _entry: &ReportEntry, _message_id: &str, _result: MailResult) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_data(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_commit(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_message_id: &str,
|
||||||
|
_message_size: usize,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_commit(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_tx_rollback(&mut self, _entry: &ReportEntry, _message_id: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_tx_rollback(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_protocol_client(&mut self, _entry: &ReportEntry, _command: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_protocol_client(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_protocol_server(&mut self, _entry: &ReportEntry, _response: &str) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_protocol_server(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_filter_response(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_phase: FilterPhase,
|
||||||
|
_response: &str,
|
||||||
|
_param: &Option<String>,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_filter_response(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_filter_report(
|
||||||
|
&mut self,
|
||||||
|
_entry: &ReportEntry,
|
||||||
|
_filter_kind: FilterKind,
|
||||||
|
_name: &str,
|
||||||
|
_message: &str,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_filter_report(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_report_timeout(&mut self, _entry: &ReportEntry) {}
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn has_report_timeout(&self) -> bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
44
src/lib.rs
44
src/lib.rs
|
@ -1,3 +1,47 @@
|
||||||
|
//! [![Rust-OpenSMTPD on crates.io](https://img.shields.io/crates/v/opensmtpd.svg)](https://crates.io/crates/opensmtpd)
|
||||||
|
//! [![Rust-OpenSMTPD on docs.rs](https://docs.rs/opensmtpd/badge.svg)](https://docs.rs/opensmtpd/)
|
||||||
|
//! ![License: MIT or Apache-2.0](https://img.shields.io/crates/l/opensmtpd)
|
||||||
|
//!
|
||||||
|
//! # Writing a filter for OpenSMTPD
|
||||||
|
//!
|
||||||
|
//! The first step is to define an object (most of the time you want
|
||||||
|
//! a struct) the implements the [`Filter`] trait. All of this
|
||||||
|
//! trait's methods have an empty default implementation, so you only
|
||||||
|
//! have to implement the ones that matters to you. For each method
|
||||||
|
//! you implement, you must use the [`register`] macro in order to
|
||||||
|
//! ask OpenSMTPD to send you the corresponding events and filter
|
||||||
|
//! requests.
|
||||||
|
//!
|
||||||
|
//! The second and last step is to call the [`run_filter`] function
|
||||||
|
//! with a mutable reference of your filter object.
|
||||||
|
//!
|
||||||
|
//! # Examples
|
||||||
|
//!
|
||||||
|
//! The following filter increments a variable every time a client
|
||||||
|
//! disconnects.
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use opensmtpd::{register, run_filter, Filter, ReportEntry};
|
||||||
|
//!
|
||||||
|
//! struct MyCounter {
|
||||||
|
//! nb: u64,
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! impl Filter for MyCounter {
|
||||||
|
//! register!(has_report_link_disconnect);
|
||||||
|
//! fn on_report_link_disconnect(&mut self, _entry: &ReportEntry) {
|
||||||
|
//! self.nb + 1;
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! let mut my_counter = MyCounter { nb: 0, };
|
||||||
|
//! run_filter(&mut my_counter);
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! More examples can be found in the [examples directory](https://github.com/breard-r/rust-opensmtpd/tree/main/examples).
|
||||||
|
|
||||||
mod data_structures;
|
mod data_structures;
|
||||||
mod filter;
|
mod filter;
|
||||||
mod io;
|
mod io;
|
||||||
|
|
Reference in a new issue