expose fewer internals in packages, for easier software reuse

- prometheus is now behind an interface, they aren't dependencies for the
  reusable components anymore.
- some dependencies have been inverted: instead of packages importing a main
  package to get configuration, the main package now sets configuration in
  these packages. that means fewer internals are pulled in.
- some functions now have new parameters for values that were retrieved from
  package "mox-".
This commit is contained in:
Mechiel Lukkien
2023-12-05 21:13:57 +01:00
parent fcaa504878
commit 72ac1fde29
51 changed files with 696 additions and 568 deletions

View File

@ -37,16 +37,20 @@ import (
"github.com/mjl-/mox/autotls"
"github.com/mjl-/mox/config"
"github.com/mjl-/mox/dkim"
"github.com/mjl-/mox/dns"
"github.com/mjl-/mox/message"
"github.com/mjl-/mox/mlog"
"github.com/mjl-/mox/moxio"
"github.com/mjl-/mox/moxvar"
"github.com/mjl-/mox/mtasts"
"github.com/mjl-/mox/smtp"
)
var pkglog = mlog.New("mox", nil)
// Pedantic enables stricter parsing.
var Pedantic bool
// Config paths are set early in program startup. They will point to files in
// the same directory.
var (
@ -397,7 +401,16 @@ func SetConfig(c *Config) {
}
}
moxvar.Pedantic = c.Static.Pedantic
SetPedantic(c.Static.Pedantic)
}
// Set pedantic in all packages.
func SetPedantic(p bool) {
dkim.Pedantic = p
dns.Pedantic = p
message.Pedantic = p
smtp.Pedantic = p
Pedantic = p
}
// ParseConfig parses the static config at path p. If checkOnly is true, no changes

65
mox-/dkimsign.go Normal file
View File

@ -0,0 +1,65 @@
package mox
import (
"bytes"
"context"
"fmt"
"strings"
"time"
"github.com/mjl-/mox/config"
"github.com/mjl-/mox/dkim"
"github.com/mjl-/mox/dns"
"github.com/mjl-/mox/mlog"
"github.com/mjl-/mox/smtp"
)
// DKIMSelectors returns the selectors to use for signing.
func DKIMSelectors(dkimConf config.DKIM) []dkim.Selector {
var l []dkim.Selector
for _, sign := range dkimConf.Sign {
sel := dkimConf.Selectors[sign]
s := dkim.Selector{
Hash: sel.HashEffective,
HeaderRelaxed: sel.Canonicalization.HeaderRelaxed,
BodyRelaxed: sel.Canonicalization.BodyRelaxed,
Headers: sel.HeadersEffective,
SealHeaders: !sel.DontSealHeaders,
Expiration: time.Duration(sel.ExpirationSeconds) * time.Second,
PrivateKey: sel.Key,
Domain: sel.Domain,
}
l = append(l, s)
}
return l
}
// DKIMSign looks up the domain for "from", and uses its DKIM configuration to
// generate DKIM-Signature headers, for inclusion in a message. The
// DKIM-Signatur headers, are returned. If no domain was found an empty string and
// nil error is returned.
func DKIMSign(ctx context.Context, log mlog.Log, from smtp.Path, smtputf8 bool, data []byte) (string, error) {
// Add DKIM signature for domain, even if higher up than the full mail hostname.
// This helps with an assumed (because default) relaxed DKIM policy. If the DMARC
// policy happens to be strict, the signature won't help, but won't hurt either.
fd := from.IPDomain.Domain
var zerodom dns.Domain
for fd != zerodom {
confDom, ok := Conf.Domain(fd)
if !ok {
var nfd dns.Domain
_, nfd.ASCII, _ = strings.Cut(fd.ASCII, ".")
_, nfd.Unicode, _ = strings.Cut(fd.Unicode, ".")
fd = nfd
continue
}
selectors := DKIMSelectors(confDom.DKIM)
dkimHeaders, err := dkim.Sign(ctx, log.Logger, from.Localpart, fd, selectors, smtputf8, bytes.NewReader(data))
if err != nil {
return "", fmt.Errorf("dkim sign for domain %s: %v", fd, err)
}
return dkimHeaders, nil
}
return "", nil
}

View File

@ -1,29 +0,0 @@
package mox
import (
"crypto/tls"
"fmt"
)
// TLSInfo returns human-readable strings about the TLS connection, for use in
// logging.
func TLSInfo(conn *tls.Conn) (version, ciphersuite string) {
st := conn.ConnectionState()
versions := map[uint16]string{
tls.VersionTLS10: "TLS1.0",
tls.VersionTLS11: "TLS1.1",
tls.VersionTLS12: "TLS1.2",
tls.VersionTLS13: "TLS1.3",
}
v, ok := versions[st.Version]
if ok {
version = v
} else {
version = fmt.Sprintf("TLS %x", st.Version)
}
ciphersuite = tls.CipherSuiteName(st.CipherSuite)
return
}