viaspf

The viaspf library contains a complete implementation of the Sender Policy Framework (SPF) specification, version 1, as described in [RFC 7208]. It provides an asynchronous API for checking an email sender’s authorisation according to the specification.

This library implements the core SPF protocol, but it does not directly depend on a DNS resolver. Instead, users of this library can provide an implementation of a DNS lookup trait, and so choose themselves which DNS resolver they want to use to implement their SPF verifier applications.

The implementation uses [Tokio], but for the timeout logic only. If needed, it is possible to use a different async runtime for driving the library by toggling certain Cargo features.

This library was first created in a ‘clean room’ setting. It was written from scratch, referring only to the RFC, and following it to the letter. Extensive checking ensures correctness and conformance with RFC 7208.

The minimum supported Rust version is 1.56.1.

Usage

This is a Rust library. Include viaspf in Cargo.toml as usual. For ease of use, you may want to enable the feature trust-dns-resolver; see below.

The main purpose of the viaspf library is SPF verification, that is, checking whether a sending host is authorised to use some mail domain according to published SPF policy. The function [evaluate_sender] is provided as the main API item.

```rust use std::net::IpAddr; use viaspf::*;

let config = Default::default(); let ip = IpAddr::from([1, 2, 3, 4]); let mail_from = "amy@example.org";

let spfresult = match mailfrom.parse() { Ok(sender) => { evaluatesender(&resolver, &config, ip, &sender, None) .await .spfresult } _ => SpfResult::None, };

asserteq!(spfresult, SpfResult::Pass); ```

The example above is straightforward. It demonstrates checking of the MAIL FROM identity amy@example.org.

The first argument, resolver, deserves a brief explanation. While viaspf contains a complete implementation of the SPF protocol, it does not itself include DNS resolution capabilities. Instead, DNS resolution is abstracted into the trait [Lookup], and is thus ‘pluggable’. Provide an implementation of this trait using the resolver of your choice to control how DNS queries are done.

As a convenience, the Cargo feature trust-dns-resolver can be enabled to make an implementation of Lookup available for the [Trust-DNS] resolver.

Refer to the [API documentation] for details.

Examples

A simple SPF verifier is included as an executable example: the command-line tool spfquery. This program uses the [Trust-DNS] resolver to perform DNS lookups.

Pass an IP address and a domain name as arguments to spfquery. The query is then evaluated and the result and a trace is printed out.

cargo run --features trust-dns-resolver \ --example spfquery -- 185.46.57.247 gluet.ch

IP: 185.46.57.247 Domain: gluet.ch SPF result: pass Mechanism: mx Trace: executing SPF query for domain "gluet.ch" looking up TXT records for "gluet.ch" evaluating SPF record "v=spf1 mx -all" evaluating directive "mx" evaluating mechanism "mx" incrementing global lookup count using target name "gluet.ch" looking up MX records for "gluet.ch" trying MX name "mail.gluet.ch" incrementing global lookup count looking up A records for "mail.gluet.ch" trying IP address 185.46.57.247 incrementing per-mechanism lookup count mechanism matched evaluated directive to result "pass"

Licence

Copyright © 2020–2022 David Bürgin

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.