1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-19 14:57:04 +00:00

chasquid: Add SPF checks

This patch makes chasquid perform SPF checks, and add the corresponding
Received-SPF header.
This commit is contained in:
Alberto Bertogli
2016-10-07 23:55:28 +01:00
parent 3d3b771b80
commit 2b801a84d1
2 changed files with 32 additions and 4 deletions

View File

@@ -26,6 +26,7 @@ import (
"blitiri.com.ar/go/chasquid/internal/envelope" "blitiri.com.ar/go/chasquid/internal/envelope"
"blitiri.com.ar/go/chasquid/internal/queue" "blitiri.com.ar/go/chasquid/internal/queue"
"blitiri.com.ar/go/chasquid/internal/set" "blitiri.com.ar/go/chasquid/internal/set"
"blitiri.com.ar/go/chasquid/internal/spf"
"blitiri.com.ar/go/chasquid/internal/systemd" "blitiri.com.ar/go/chasquid/internal/systemd"
"blitiri.com.ar/go/chasquid/internal/tlsconst" "blitiri.com.ar/go/chasquid/internal/tlsconst"
"blitiri.com.ar/go/chasquid/internal/trace" "blitiri.com.ar/go/chasquid/internal/trace"
@@ -405,6 +406,10 @@ type Conn struct {
rcptTo []string rcptTo []string
data []byte data []byte
// SPF results.
spfResult spf.Result
spfError error
// Are we using TLS? // Are we using TLS?
onTLS bool onTLS bool
@@ -593,6 +598,10 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
return 500, "malformed command - " + err.Error() return 500, "malformed command - " + err.Error()
} }
// Note some servers check (and fail) if we had a previous MAIL command,
// but that's not according to the RFC. We reset the envelope instead.
c.resetEnvelope()
// Special case a null reverse-path, which is explicitly allowed and used // Special case a null reverse-path, which is explicitly allowed and used
// for notification messages. // for notification messages.
// It should be written "<>", we check for that and remove spaces just to // It should be written "<>", we check for that and remove spaces just to
@@ -611,15 +620,25 @@ func (c *Conn) MAIL(params string) (code int, msg string) {
return 501, "sender address must contain a domain" return 501, "sender address must contain a domain"
} }
// SPF check - https://tools.ietf.org/html/rfc7208#section-2.4
if tcp, ok := c.netconn.RemoteAddr().(*net.TCPAddr); ok {
c.spfResult, c.spfError = spf.CheckHost(
tcp.IP, envelope.DomainOf(e.Address))
// https://tools.ietf.org/html/rfc7208#section-8
// We opt not to fail on errors, to avoid accidents to prevent
// delivery.
if c.spfResult == spf.Fail {
return 550, fmt.Sprintf(
"SPF check failed: %v", c.spfError)
}
}
e.Address, err = envelope.IDNAToUnicode(e.Address) e.Address, err = envelope.IDNAToUnicode(e.Address)
if err != nil { if err != nil {
return 501, "malformed address (IDNA conversion failed)" return 501, "malformed address (IDNA conversion failed)"
} }
}
// Note some servers check (and fail) if we had a previous MAIL command, }
// but that's not according to the RFC. We reset the envelope instead.
c.resetEnvelope()
c.mailFrom = e.Address c.mailFrom = e.Address
return 250, "You feel like you are being watched" return 250, "You feel like you are being watched"
@@ -752,6 +771,12 @@ func (c *Conn) addReceivedHeader() {
// https://tools.ietf.org/html/rfc5322#section-3.6.7 // https://tools.ietf.org/html/rfc5322#section-3.6.7
v += fmt.Sprintf("on ; %s\n", time.Now().Format(time.RFC1123Z)) v += fmt.Sprintf("on ; %s\n", time.Now().Format(time.RFC1123Z))
c.data = envelope.AddHeader(c.data, "Received", v) c.data = envelope.AddHeader(c.data, "Received", v)
if c.spfResult != "" {
// https://tools.ietf.org/html/rfc7208#section-9.1
v = fmt.Sprintf("%s (%v)", c.spfResult, c.spfError)
c.data = envelope.AddHeader(c.data, "Received-SPF", v)
}
} }
func (c *Conn) STARTTLS(params string, tr *trace.Trace) (code int, msg string) { func (c *Conn) STARTTLS(params string, tr *trace.Trace) (code int, msg string) {
@@ -869,6 +894,8 @@ func (c *Conn) resetEnvelope() {
c.mailFrom = "" c.mailFrom = ""
c.rcptTo = nil c.rcptTo = nil
c.data = nil c.data = nil
c.spfResult = ""
c.spfError = nil
} }
func (c *Conn) userExists(addr string) bool { func (c *Conn) userExists(addr string) bool {

View File

@@ -20,6 +20,7 @@ Delivery to the following recipient(s) failed permanently:
----- Original message ----- ----- Original message -----
Received-SPF: *
Received: from user user@testserver Received: from user user@testserver
by * by *
(envelope from "user@testserver") (envelope from "user@testserver")