all repos — navani @ 6a3b4b68a2ff0917e49e2eeb42f8d6b99281fb1d

forlater's primary mail processing service

mail/check.go (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
package mail

import (
	"fmt"
	"net"
	"net/mail"
	"strings"

	"blitiri.com.ar/go/spf"
	"golang.org/x/net/idna"
)

func VerifySPF(email string) (bool, error) {
	e, err := mail.ParseAddress(email)
	if err != nil {
		return false, fmt.Errorf("parse address: %w", err)
	}
	domain := strings.Split(e.Address, "@")[1]

	domain, err = idna.ToASCII(domain)
	if err != nil {
		return false, fmt.Errorf("to ascii: %w\n", err)
	}

	mxs, err := net.LookupMX(domain)
	if err != nil {
		return false, fmt.Errorf("mx lookup: %w\n", err)
	}

	passes := []spf.Result{}
	for _, mx := range mxs {
		ips, err := net.LookupIP(mx.Host)
		if err != nil {
			return false, fmt.Errorf("ip lookup: %w\n", err)
		}

		for _, ip := range ips {
			result, _ := spf.CheckHostWithSender(ip, domain, e.Address)
			if result == spf.Pass {
				passes = append(passes, result)
			}
		}
	}

	if len(passes) > 0 {
		return true, nil
	} else {
		return false, nil
	}
}