Skip to content

A lightweight and standards-compliant SPF (Sender Policy Framework) record evaluator written in Go. anotherspf performs DNS-based SPF validation, supports IPv4/IPv6, includes rule parsing, DNS lookup limits, and is designed to be easily embeddable in mail servers or email validation tools.

License

Notifications You must be signed in to change notification settings

kisshan13/anotherspf

Repository files navigation

anotherspf

Go Reference

anotherspf is a lightweight and standards-compliant SPF (Sender Policy Framework) record evaluator written in Go. It performs DNS-based SPF validation for a given IP, sender, and domain, supporting full SPF rule parsing, macro expansion, DNS lookup limits, and recursive evaluation of modifiers like include and redirect.

Install

go get github.com/kisshan13/anotherspf

Features

  • RFC 7208-compliant SPF evaluation

  • Supports IPv4 and IPv6

  • Enforces 10-DNS-lookup limit per SPF spec

  • Evaluates SPF mechanisms and modifiers:

    • a, mx, ip4, ip6, include, exists, all
    • redirect, exp
  • Expands macros like %{s}, %{i}, %{h}, %{d} etc.

  • Thread-safe and embeddable in other applications


Usage

info, err := anotherspf.Check("192.0.2.1", "example.com", "[email protected]")
if err != nil {
    log.Fatal(err)
}
fmt.Println("SPF result:", info.Status)

Core Function

func Check(ip string, domain string, sender string) (*SPFInfo, error)

Evaluates the SPF record for the given sender IP, domain, and envelope sender address.

  • Retrieves TXT records
  • Parses the SPF string
  • Evaluates SPF mechanisms and modifiers recursively
  • Returns a structured SPFInfo object and evaluation result

Types

type SPFInfo

Tracks state and result of an SPF evaluation.

type SPFInfo struct {
    LookupCount int
    Lookups     map[string]*Lookup
    lookedDns   map[string]bool
    Status      Result
    PassedRule  *Rule
    Rule        []*Rule
    Record      string
    mu          sync.Mutex
}

type Rule

Represents a parsed SPF rule (mechanism or modifier).

type Rule struct {
    Modifier      Modifier
    Mechanism     Mechanism
    Qualifier     Qualifier
    ContainsMacro bool
    Key           string
    Value         string
}

type MacroContext

Carries contextual variables for SPF macro expansion.

type MacroContext struct {
    Sender        string
    IP            string
    Helo          string
    Domain        string
    Authoritative string
}

type Result

Possible SPF evaluation results:

const (
    Pass      Result = "pass"
    Fail      Result = "fail"
    SoftFail  Result = "softfail"
    Neutral   Result = "neutral"
    TempError Result = "temperror"
    PermError Result = "permerror"
    None      Result = "none"
)

Mechanisms & Modifiers

Supported SPF Mechanisms:

  • ip4, ip6
  • a, mx, exists
  • include, all

Modifiers:

  • redirect=<domain>
  • exp=<explanation>
  • Unknown modifiers are parsed but ignored.

Qualifiers:

const (
    QPass     = "+"
    QFail     = "-"
    QSoftFail = "~"
    QNeutral  = "?"
)

🔐 DNS Lookup Handling

  • Enforces a strict maximum of 10 DNS lookups
  • Deduplicates A, MX, and TXT queries per host
  • Fails with PermError if the limit is exceeded

🧪 Internals

evalRules(...)

Recursively evaluates parsed rules with DNS checks.

expandMacros(...)

Expands macros in SPF strings based on context.

parse(...)

Parses SPF TXT records into a structured rule list.


📄 License

MIT — See the GitHub repository for details.


About

A lightweight and standards-compliant SPF (Sender Policy Framework) record evaluator written in Go. anotherspf performs DNS-based SPF validation, supports IPv4/IPv6, includes rule parsing, DNS lookup limits, and is designed to be easily embeddable in mail servers or email validation tools.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages