1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2026-01-07 17:47:14 +00:00

Remove the MTA-STS (Strict Transport Security) implementation

This commit removes the experimental MTA-STS (Strict Transport Security)
implementation for now, as it's not up to date with the latest draft.

Development will continue on the "sts" branch, but this way it won't
block releases until it is ready.

Commits reverted:
 - cb6500b993
 - 0eeb964534
 - e66288e4b4
 - 216cf47ffa
 - d66b06de51
 - fe00750e39
 - 933ab54cd8
This commit is contained in:
Alberto Bertogli
2017-04-11 00:39:21 +01:00
parent 213bc63a95
commit 7f5bedf4aa
6 changed files with 14 additions and 942 deletions

View File

@@ -1,7 +1,6 @@
package courier
import (
"context"
"crypto/tls"
"expvar"
"flag"
@@ -14,7 +13,6 @@ import (
"blitiri.com.ar/go/chasquid/internal/domaininfo"
"blitiri.com.ar/go/chasquid/internal/envelope"
"blitiri.com.ar/go/chasquid/internal/smtp"
"blitiri.com.ar/go/chasquid/internal/sts"
"blitiri.com.ar/go/chasquid/internal/trace"
)
@@ -28,11 +26,6 @@ var (
smtpPort = flag.String("testing__outgoing_smtp_port", "25",
"port to use for outgoing SMTP connections, ONLY FOR TESTING")
// Enable STS policy checking; this is an experimental flag and will be
// removed in the future, once this is made the default.
enableSTS = flag.Bool("experimental__enable_sts", false,
"enable STS policy checking; EXPERIMENTAL")
// Fake MX records, used for testing only.
fakeMX = map[string][]string{}
)
@@ -41,25 +34,20 @@ var (
var (
tlsCount = expvar.NewMap("chasquid/smtpOut/tlsCount")
slcResults = expvar.NewMap("chasquid/smtpOut/securityLevelChecks")
stsSecurityModes = expvar.NewMap("chasquid/smtpOut/sts/mode")
stsSecurityResults = expvar.NewMap("chasquid/smtpOut/sts/security")
)
// SMTP delivers remote mail via outgoing SMTP.
type SMTP struct {
Dinfo *domaininfo.DB
STSCache *sts.PolicyCache
Dinfo *domaininfo.DB
}
func (s *SMTP) Deliver(from string, to string, data []byte) (error, bool) {
a := &attempt{
courier: s,
from: from,
to: to,
data: data,
toDomain: envelope.DomainOf(to),
tr: trace.New("Courier.SMTP", to),
courier: s,
from: from,
to: to,
data: data,
tr: trace.New("Courier.SMTP", to),
}
defer a.tr.Finish()
a.tr.Debugf("%s -> %s", from, to)
@@ -69,9 +57,8 @@ func (s *SMTP) Deliver(from string, to string, data []byte) (error, bool) {
a.from = ""
}
a.stsPolicy = s.fetchSTSPolicy(a.tr, a.toDomain)
mxs, err := lookupMXs(a.tr, a.toDomain, a.stsPolicy)
toDomain := envelope.DomainOf(to)
mxs, err := lookupMXs(a.tr, toDomain)
if err != nil || len(mxs) == 0 {
// Note this is considered a permanent error.
// This is in line with what other servers (Exim) do. However, the
@@ -117,8 +104,6 @@ type attempt struct {
toDomain string
helloDomain string
stsPolicy *sts.Policy
tr *trace.Trace
}
@@ -186,18 +171,6 @@ retry:
}
slcResults.Add("pass", 1)
if a.stsPolicy != nil && a.stsPolicy.Mode == sts.Enforce {
// The connection MUST be validated TLS.
// https://tools.ietf.org/html/draft-ietf-uta-mta-sts-03#section-4.2
if secLevel != domaininfo.SecLevel_TLS_SECURE {
stsSecurityResults.Add("fail", 1)
return a.tr.Errorf("invalid security level (%v) for STS policy",
secLevel), false
}
stsSecurityResults.Add("pass", 1)
a.tr.Debugf("STS policy: connection is using valid TLS")
}
if err = c.MailAndRcpt(a.from, a.to); err != nil {
return a.tr.Errorf("MAIL+RCPT %v", err), smtp.IsPermanent(err)
}
@@ -222,29 +195,7 @@ retry:
return nil, false
}
func (s *SMTP) fetchSTSPolicy(tr *trace.Trace, domain string) *sts.Policy {
if !*enableSTS {
return nil
}
if s.STSCache == nil {
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
policy, err := s.STSCache.Fetch(ctx, domain)
if err != nil {
return nil
}
tr.Debugf("got STS policy")
stsSecurityModes.Add(string(policy.Mode), 1)
return policy
}
func lookupMXs(tr *trace.Trace, domain string, policy *sts.Policy) ([]string, error) {
func lookupMXs(tr *trace.Trace, domain string) ([]string, error) {
if v, ok := fakeMX[domain]; ok {
return v, nil
}
@@ -288,39 +239,12 @@ func lookupMXs(tr *trace.Trace, domain string, policy *sts.Policy) ([]string, er
// This case is explicitly covered by the SMTP RFC.
// https://tools.ietf.org/html/rfc5321#section-5.1
mxs = filterMXs(tr, policy, mxs)
if len(mxs) == 0 {
tr.Errorf("domain %q has no valid MX/A record", domain)
} else if len(mxs) > 5 {
// Cap the list of MXs to 5 hosts, to keep delivery attempt times
// sane and prevent abuse.
// Cap the list of MXs to 5 hosts, to keep delivery attempt times sane
// and prevent abuse.
if len(mxs) > 5 {
mxs = mxs[:5]
}
tr.Debugf("MXs: %v", mxs)
return mxs, nil
}
func filterMXs(tr *trace.Trace, p *sts.Policy, mxs []string) []string {
if p == nil {
return mxs
}
filtered := []string{}
for _, mx := range mxs {
if p.MXIsAllowed(mx) {
filtered = append(filtered, mx)
} else {
tr.Printf("MX %q not allowed by policy, skipping", mx)
}
}
// We don't want to return an empty set if the mode is not enforce.
// This prevents failures for policies in reporting mode.
// https://tools.ietf.org/html/draft-ietf-uta-mta-sts-03#section-5.2
if len(filtered) == 0 && p.Mode != sts.Enforce {
filtered = mxs
}
return filtered
}

View File

@@ -23,7 +23,7 @@ func newSMTP(t *testing.T) (*SMTP, string) {
t.Fatal(err)
}
return &SMTP{dinfo, nil}, dir
return &SMTP{dinfo}, dir
}
// Fake server, to test SMTP out.