spf

package module
v0.0.0-...-ca1bff5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2023 License: MIT Imports: 4 Imported by: 0

README

Go-SPF

TL;DR

To add this package to your go imports, use

go get github.com/moverval/go-spf

This package provides easy to use features, to validate, if an IP belongs to a network. It supports all spf1 mechanisms and the redirect modifier.

To check if an ip belongs to a network

// ValidateIP(ip, domain, nameserver, follows)
result, err := spf.ValidateIP(net.ParseIP("35.190.247.10"), "gmail.com", "8.8.8.8:53", 3)

if err != nil {
    // handle error
}

switch result {
case spf.PassQualifier:
    // IP belongs to network
case spf.NeutralQualifier:
    // IP was found but no conclusion can be made
case spf.NoneQualifier:
    // No match was found for the ip. This should be treated as Neutral
case spf.SoftFailQualifier:
    // IP is probably not from the network
case spf.FailQualifier:
    // IP is not from the network
}

Errors

All custom error types can be seen in errors.go. If an error get's thrown, it is most of the time the issuers fault, but errors can also occur if a dns record could not be resolved.

Examples of errors:

  • Syntax

The spf record has an invalid syntax.

  • OutOfRecursions

The issuer exceeded the include or redirect depth. (Use -1 to make the depth infinite; not recommended)

Lookup SPF

SPF can also only be queried. If you only want the spf record string, use LookupSPF

record, err := spf.LookupSPF("gmail.com", "8.8.8.8:53")

if err != nil {
    // handle error
}

// do something with the record

Parse SPF

This library has a custom parser to evaluate spf strings. It handles strings gracefully and tries to interpret them correctly even if they are false.

result, err := spf.ParseSPF("v=spf1 -include:ban.voulter.com include:spf.voulter.com include:spf2.voulter.com a:voulter.com ip4:127.0.0.1 ip6:::1 ~all")

var expected spf.Record = []spf.Mechanism{
    {Qualifier: spf.FailQualifier, Mechanism: spf.IncludeMechanism, Value: "ban.voulter.com"},
    {Qualifier: spf.PassQualifier, Mechanism: spf.IncludeMechanism, Value: "spf.voulter.com"},
    {Qualifier: spf.PassQualifier, Mechanism: spf.IncludeMechanism, Value: "spf2.voulter.com"},
    {Qualifier: spf.PassQualifier, Mechanism: spf.AMechanism, Value: "voulter.com"},
    {Qualifier: spf.PassQualifier, Mechanism: spf.IPv4Mechanism, Value: "127.0.0.1"},
    {Qualifier: spf.PassQualifier, Mechanism: spf.IPv6Mechanism, Value: "::1"},
    {Qualifier: spf.SoftFailQualifier, Mechanism: spf.AllMechanism, Value: ""},
}

if err != nil {
    // handle error
    // an error should not occur in this example
}

if reflect.DeepEqual(result, expected) {
    // this is true
}

Advanced: Partial Parse SPF

Because Subcomponents are exposed by design, it is possible the evaluate individual Mechanisms seperately. For more information look at interpreter.go/ExecuteMechanism.

Documentation

Index

Constants

View Source
const (
	PassQualifier     = iota // +
	FailQualifier            // -
	SoftFailQualifier        // ~
	NeutralQualifier         // ?
	NoneQualifier            // No Mechanism matched the current ip
)

A Qualifier can be -, +, ~, ?

View Source
const (
	AllMechanism      = iota + 1 // all
	IPv4Mechanism                // ip4
	IPv6Mechanism                // ip6
	AMechanism                   // a
	MXMechanism                  // mx
	PTRMechanism                 // ptr
	ExistsMechanism              // exists
	IncludeMechanism             // include
	RedirectMechanism            // redirect
)

Caution! Modifiers are also called mechanisms in this library, but they get distinguished correctly

Variables

View Source
var ErrInvalidMechanism error = errors.New("invalidmechanism") // Unknwon mechanism keyword received
View Source
var ErrInvalidModifier error = errors.New("invalidmodifier") // Unknown modifier received
View Source
var ErrInvalidQualifier error = errors.New("invalidqualifier") // Other character than +, -, ~, ? for a qualifier received
View Source
var ErrNotFound error = errors.New("notfound") // DNS entry not found
View Source
var ErrOutOfRecursions = errors.New("outofrecursions") // Too many redirect or include mechanisms were called
View Source
var ErrSyntax error = errors.New("syntax") // Syntax error in ParseSPF

Functions

func IsSPF

func IsSPF(spf string) bool

Simple and fast check to validate SPF Record

func LookupARec

func LookupARec(domain string, nameserver string) (net.IP, error)

Returns first a record as net.IP

Returns an error if dns name couldn't be resolved

func LookupSPF

func LookupSPF(domain string, nameserver string) (string, error)

Get an SPF Record as string from a domain

Returns an error if no spf record is found or dns name couldn't be resolved

func MatchIP

func MatchIP(ip net.IP, ip2 string) (bool, error)

func MatchIPWithARec

func MatchIPWithARec(ip net.IP, domain string, nameserver string) (bool, error)

Checks if ip is contained in a record

Returns an error if dns name couldn't be resolved

func MatchIPWithCIDR

func MatchIPWithCIDR(ip net.IP, cidr string) (bool, error)

Check if ip exists in a network

Returns an error if cidr is invalid

func MatchIPWithMXRec

func MatchIPWithMXRec(ip net.IP, domain string, nameserver string) (bool, error)

Checks if ip is found in a record which was referenced by mx record

Returns an error if dns name couldn't be resolved

func MatchIPWithPtrRec

func MatchIPWithPtrRec(ip net.IP, domain string, nameserver string) (bool, error)

Checks if ip resolves to domain name of variable domain

Returns an error if dns name couldn't be resolved

Types

type Mechanism

type Mechanism struct {
	Qualifier Qualifier
	Mechanism int
	Value     string
}

An Argument in the SPF Record They are read from left to right (Left is the most powerful one) Qualifiers determine how the ip should be treated if the mechanism matches the address

func EvaluateMechanism

func EvaluateMechanism(context *MechanismParseContext) (Mechanism, error)

func EvaluateModifier

func EvaluateModifier(context *MechanismParseContext) (Mechanism, error)

type MechanismParseContext

type MechanismParseContext struct {
	Qualifier         Qualifier
	Mechanism         string
	Value             string
	WritingDescriptor bool
	Modifier          bool
}

type Qualifier

type Qualifier int

func EvaluateQualifier

func EvaluateQualifier(char rune) (Qualifier, error)

func ExecuteMechanism

func ExecuteMechanism(ip net.IP, mechanism Mechanism, nameserver string, depth int) (Qualifier, error)

Make exact queries or execute a part of a record. This is used by ValidateIP

func ValidateIP

func ValidateIP(ip net.IP, name string, nameserver string, depth int) (Qualifier, error)

Returns the qualifier of a domain for given IP

ValidateIP can check number of recursions subrecords until it gives up. To check infinitely, use a negative value

type Record

type Record []Mechanism

The mechanisms which were found in an SPF Record. This Type is sorted from the most to the least powerful mechanism.

func ParseSPF

func ParseSPF(spf string) (Record, error)

Informationful way to read out spf record

type Result

type Result string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL