#spf #email #smtp #dns #domain

viaspf

Implementation of the Sender Policy Framework (SPF) specification

18 releases

Uses new Rust 2021

0.4.1 May 30, 2022
0.4.0 Mar 6, 2022
0.4.0-alpha.2 Oct 18, 2021
0.4.0-alpha.1 Jul 2, 2021
0.0.2 Jul 4, 2020

#6 in Email

Download history 29/week @ 2022-03-10 116/week @ 2022-03-17 14/week @ 2022-03-24 24/week @ 2022-03-31 33/week @ 2022-04-07 45/week @ 2022-04-14 87/week @ 2022-04-21 197/week @ 2022-04-28 173/week @ 2022-05-05 320/week @ 2022-05-12 314/week @ 2022-05-19 600/week @ 2022-05-26 762/week @ 2022-06-02 471/week @ 2022-06-09 549/week @ 2022-06-16 361/week @ 2022-06-23

2,309 downloads per month
Used in 8 crates (4 directly)

GPL-3.0-or-later

220KB
4.5K SLoC

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.

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 spf_result = match mail_from.parse() {
    Ok(sender) => {
        evaluate_sender(&resolver, &config, ip, &sender, None)
            .await
            .spf_result
    }
    _ => SpfResult::None,
};

assert_eq!(spf_result, 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 per-mechanism lookup count
  looking up A records for "mail.gluet.ch"
  trying IP address 185.46.57.247
  mechanism matched
  evaluated directive to result "pass"
  evaluated SPF query 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.

Dependencies

~1.5–8MB
~168K SLoC