mirror of
https://blitiri.com.ar/repos/chasquid
synced 2026-10-28 15:02:28 +00:00
domaininfo: New package to track domain (security) information
This patch introduces a new "domaininfo" package, which implements a database with information about domains. In particular, it tracks incoming and outgoing security levels. That information is used in incoming and outgoing SMTP to prevent downgrades.
This commit is contained in:
+58
-5
@@ -19,6 +19,9 @@ import (
|
||||
|
||||
"blitiri.com.ar/go/chasquid/internal/aliases"
|
||||
"blitiri.com.ar/go/chasquid/internal/courier"
|
||||
"blitiri.com.ar/go/chasquid/internal/domaininfo"
|
||||
"blitiri.com.ar/go/chasquid/internal/spf"
|
||||
"blitiri.com.ar/go/chasquid/internal/trace"
|
||||
"blitiri.com.ar/go/chasquid/internal/userdb"
|
||||
|
||||
"github.com/golang/glog"
|
||||
@@ -169,7 +172,7 @@ func TestWrongMailParsing(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.Mail("from@from"); err != nil {
|
||||
if err := c.Mail("from@plain"); err != nil {
|
||||
t.Errorf("Mail: %v", err)
|
||||
}
|
||||
|
||||
@@ -200,11 +203,11 @@ func TestRcptBeforeMail(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRcptOption(t *testing.T) {
|
||||
c := mustDial(t, ModeSMTP, false)
|
||||
c := mustDial(t, ModeSMTP, true)
|
||||
defer c.Close()
|
||||
|
||||
if err := c.Mail("from@localhost"); err != nil {
|
||||
t.Errorf("Mail: %v", err)
|
||||
t.Fatalf("Mail: %v", err)
|
||||
}
|
||||
|
||||
params := []string{
|
||||
@@ -250,7 +253,7 @@ func TestReset(t *testing.T) {
|
||||
c := mustDial(t, ModeSMTP, false)
|
||||
defer c.Close()
|
||||
|
||||
if err := c.Mail("from@from"); err != nil {
|
||||
if err := c.Mail("from@plain"); err != nil {
|
||||
t.Fatalf("MAIL FROM: %v", err)
|
||||
}
|
||||
|
||||
@@ -258,7 +261,7 @@ func TestReset(t *testing.T) {
|
||||
t.Errorf("RSET: %v", err)
|
||||
}
|
||||
|
||||
if err := c.Mail("from@from"); err != nil {
|
||||
if err := c.Mail("from@plain"); err != nil {
|
||||
t.Errorf("MAIL after RSET: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -278,6 +281,55 @@ func TestRepeatedStartTLS(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecLevel(t *testing.T) {
|
||||
// We can't simulate this externally because of the SPF record
|
||||
// requirement, so do a narrow test on Conn.secLevelCheck.
|
||||
tmpDir, err := ioutil.TempDir("", "chasquid_test:")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create temp dir: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
dinfo, err := domaininfo.New(tmpDir)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create domain info: %v", err)
|
||||
}
|
||||
|
||||
c := &Conn{
|
||||
tr: trace.New("testconn", "testconn"),
|
||||
dinfo: dinfo,
|
||||
}
|
||||
|
||||
// No SPF, skip security checks.
|
||||
c.spfResult = spf.None
|
||||
c.onTLS = true
|
||||
if !c.secLevelCheck("from@slc") {
|
||||
t.Fatalf("TLS seclevel failed")
|
||||
}
|
||||
|
||||
c.onTLS = false
|
||||
if !c.secLevelCheck("from@slc") {
|
||||
t.Fatalf("plain seclevel failed, even though SPF does not exist")
|
||||
}
|
||||
|
||||
// Now the real checks, once SPF passes.
|
||||
c.spfResult = spf.Pass
|
||||
|
||||
if !c.secLevelCheck("from@slc") {
|
||||
t.Fatalf("plain seclevel failed")
|
||||
}
|
||||
|
||||
c.onTLS = true
|
||||
if !c.secLevelCheck("from@slc") {
|
||||
t.Fatalf("TLS seclevel failed")
|
||||
}
|
||||
|
||||
c.onTLS = false
|
||||
if c.secLevelCheck("from@slc") {
|
||||
t.Fatalf("plain seclevel worked, downgrade was allowed")
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// === Benchmarks ===
|
||||
//
|
||||
@@ -438,6 +490,7 @@ func realMain(m *testing.M) int {
|
||||
localC := &courier.Procmail{}
|
||||
remoteC := &courier.SMTP{}
|
||||
s.InitQueue(tmpDir+"/queue", localC, remoteC)
|
||||
s.InitDomainInfo(tmpDir + "/domaininfo")
|
||||
|
||||
udb := userdb.New("/dev/null")
|
||||
udb.AddUser("testuser", "testpasswd")
|
||||
|
||||
Reference in New Issue
Block a user