Function viaspf::evaluate_sender

source ·
pub async fn evaluate_sender(
    lookup: &impl Lookup,
    config: &Config,
    ip: IpAddr,
    sender: &Sender,
    helo_domain: Option<&DomainName>
) -> QueryResult
Expand description

Performs an SPF query and evaluation for some sender identity.

This function corresponds to the check_host() function of RFC 7208. The correspondence is not exact: The ip argument matches <ip>. The sender argument covers both <sender> and <domain> (= the domain part of <sender>). Finally, the helo_domain argument covers an argument missing in check_host(), namely, the h macro, which always evaluates to the HELO/EHLO domain.

The argument lookup is an implementation of the Lookup trait, serving as a DNS resolver. Provide an implementation yourself, or enable the Cargo feature hickory-resolver to make an implementation available for hickory_resolver::TokioAsyncResolver.

When the feature tokio-timeout is enabled (enabled by default), the query will abort after the timeout duration configured with ConfigBuilder::timeout.

§Examples

The following examples illustrate usage of this function for SPF verification of a host.

§Verifying the MAIL FROM identity

When verifying the MAIL FROM identity, the client host has presented some email address with the MAIL FROM SMTP command, for example, amy@example.org. Before that, it may also have presented some HELO/EHLO hostname, for example, mail.example.org.

Pass these inputs as the sender and helo_domain argument, respectively.

In the example, notice how in accordance with RFC 7208, section 4.3, an unusable sender identity results in SPF result none.

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

let spf_result = match mail_from.parse() {
    Ok(sender) => {
        let helo_domain = helo.parse().ok();

        evaluate_sender(&resolver, &config, ip, &sender, helo_domain.as_ref())
            .await
            .spf_result
    }
    _ => SpfResult::None,
};

assert_eq!(spf_result, SpfResult::Pass);

In the terms of the check_host() function specification,

  • <ip> then is the IP address 1.2.3.4;
  • <domain> is the domain part of the sender identity, that is example.org;
  • <sender> is the sender identity, that is amy@example.org.

§Verifying the HELO identity

When verifying the HELO identity, the client host has presented some hostname with the HELO or EHLO SMTP command, for example, mail.example.org.

Pass this input as both the sender and helo_domain argument.

In the example, notice how in accordance with RFC 7208, section 2.3, this check is only performed when the HELO string is a valid domain name.

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

let sender = Sender::from_domain(helo)?;
let helo_domain = sender.domain();

let result = evaluate_sender(&resolver, &config, ip, &sender, Some(helo_domain)).await;

assert_eq!(result.spf_result, SpfResult::Pass);

In the terms of the check_host() function specification,

  • <ip> then is the IP address 1.2.3.4;
  • <domain> is the sender identity, that is mail.example.org;
  • <sender> itself gets qualified with the local part postmaster (see section 4.3 in the RFC) to become postmaster@mail.example.org.