1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2026-02-08 22:35:58 +00:00

test: Update fuzz tests to use the built-in infrastructure

Go 1.18 supports fuzzing natively, so this patch migrates our fuzzing
tests to make use of it.
This commit is contained in:
Alberto Bertogli
2023-02-05 12:30:25 +00:00
parent a54d81f406
commit efefee9fbb
88 changed files with 246 additions and 470 deletions

10
.gitignore vendored
View File

@@ -34,13 +34,3 @@ chasquid.test
# Exclude any .pem files, to prevent accidentally including test keys and # Exclude any .pem files, to prevent accidentally including test keys and
# certificates. # certificates.
*.pem *.pem
# Ignore the generated corpus: we don't want to commit it to the repository by
# default, to avoid size blowup. Manually added corpus will begin with "t-",
# and thus not ignored.
# Leave crashers not ignored, to make them easier to spot (and they should be
# moved to manually-added corpus once detected).
**/testdata/fuzz/corpus/[0-9a-f]*
# go-fuzz build artifacts.
*-fuzz.zip

View File

@@ -1,6 +1,7 @@
package aliases package aliases
import ( import (
"bytes"
"errors" "errors"
"os" "os"
"os/exec" "os/exec"
@@ -482,3 +483,10 @@ func TestHookError(t *testing.T) {
t.Errorf("expected *exec.ExitError, got %T - %v", err, err) t.Errorf("expected *exec.ExitError, got %T - %v", err, err)
} }
} }
// Fuzz testing for the parser.
func FuzzReader(f *testing.F) {
f.Fuzz(func(t *testing.T, data []byte) {
parseReader("domain", bytes.NewReader(data))
})
}

View File

@@ -1,23 +0,0 @@
// Fuzz testing for package aliases.
//go:build gofuzz
// +build gofuzz
package aliases
import "bytes"
func Fuzz(data []byte) int {
interesting := 0
aliases, _ := parseReader("domain", bytes.NewReader(data))
// Mark cases with actual aliases as more interesting.
for _, rcpts := range aliases {
if len(rcpts) > 0 {
interesting = 1
break
}
}
return interesting
}

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("# First some valid cases.\na: b\nc: d@e, f,\nx: | command\n\n# The following is invalid, should be ignored.\na@dom: x@dom\n\n# Overrides.\no1: a\no1: b\n\n# Finally one to make the file NOT end in \\n:\ny: z\n")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\nfail: | false\n\n")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\naliasA: aliasB@srv-B\n")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\n# Easy aliases.\npepe: jose\njoan: juan\n\n# UTF-8 aliases.\npitanga: ñangapirí\nañil: azul, índigo\n\n# Pipe aliases.\ntubo: | writemailto ../.data/pipe_alias_worked\n\n")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("")

View File

@@ -1,14 +0,0 @@
# First some valid cases.
a: b
c: d@e, f,
x: | command
# The following is invalid, should be ignored.
a@dom: x@dom
# Overrides.
o1: a
o1: b
# Finally one to make the file NOT end in \n:
y: z

View File

@@ -1,12 +0,0 @@
# Easy aliases.
pepe: jose
joan: juan
# UTF-8 aliases.
pitanga: ñangapirí
añil: azul, índigo
# Pipe aliases.
tubo: | writemailto ../.data/pipe_alias_worked

View File

@@ -1,3 +0,0 @@
fail: | false

View File

@@ -1,2 +0,0 @@
aliasA: aliasB@srv-B

View File

@@ -285,3 +285,10 @@ func TestReload(t *testing.T) {
t.Errorf("unexpected error reloading wrapped backend: %v", err) t.Errorf("unexpected error reloading wrapped backend: %v", err)
} }
} }
// Fuzz testing for the response decoder, which handles user-provided data.
func FuzzDecodeResponse(f *testing.F) {
f.Fuzz(func(t *testing.T, response string) {
DecodeResponse(response)
})
}

View File

@@ -1,17 +0,0 @@
// Fuzz testing for package aliases.
//go:build gofuzz
// +build gofuzz
package auth
func Fuzz(data []byte) int {
// user, domain, passwd, err := DecodeResponse(string(data))
interesting := 0
_, _, _, err := DecodeResponse(string(data))
if err == nil {
interesting = 1
}
return interesting
}

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("@\xed\x88̥̥̥̥̥̥̄̈́̈́̈́̈́̈́̈́̈́̈́ͥ̈́̈́ͥ̓\x00\x00")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("AHVAZABwYXNz")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("dUBkAHVAZABwYXNz")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("\xeb̥̥̥̥̥̥̥̈́ͥ̈́̈́̈́̈́̈́̈́̈́̈́̈́ͥ̓@\x00\x00")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("this is not base64 encoded")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("\xeb̥̥̥̥̥̥ͯ̈́̈́̈́̈́̈́ͯ̈́̈́̈́̈́̈́̈́@\x00\x00")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("\xeb̥̥̥̥̥̥̈́̈́̈́̈́̈́ͯ̈́̈́̈́̈́̈́̈́̈́@\x00\x00")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("dUBkAABwYXNz")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("w7FhY2FAw7FlcXVlAABjbGF2YXLDqQ==")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("dUBkAABwYXNz/w==")

View File

@@ -1 +0,0 @@
dUBkAHVAZABwYXNz

View File

@@ -1 +0,0 @@
dUBkAABwYXNz

View File

@@ -1 +0,0 @@
AHVAZABwYXNz

View File

@@ -1 +0,0 @@
dUBkAABwYXNz/w==

View File

@@ -1 +0,0 @@
w7FhY2FAw7FlcXVlAABjbGF2YXLDqQ==

View File

@@ -1 +0,0 @@
this is not base64 encoded

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,16 +0,0 @@
// Fuzz testing for package normalize.
//go:build gofuzz
// +build gofuzz
package normalize
func Fuzz(data []byte) int {
s := string(data)
User(s)
Domain(s)
Addr(s)
DomainToUnicode(s)
return 0
}

View File

@@ -128,3 +128,27 @@ func TestDomainToUnicode(t *testing.T) {
} }
} }
} }
func FuzzUser(f *testing.F) {
f.Fuzz(func(t *testing.T, user string) {
User(user)
})
}
func FuzzDomain(f *testing.F) {
f.Fuzz(func(t *testing.T, domain string) {
Domain(domain)
})
}
func FuzzAddr(f *testing.F) {
f.Fuzz(func(t *testing.T, addr string) {
Addr(addr)
})
}
func FuzzDomainToUnicode(f *testing.F) {
f.Fuzz(func(t *testing.T, addr string) {
DomainToUnicode(addr)
})
}

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ÑAndÚ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("henryⅣ@throne")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ñandú")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("pé@léa")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("Pingüino")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("henryⅣthrone")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ÑAndÚ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("péléa")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ñandú")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("Pingüino")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ÑAndÚ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("henryⅣ@throne")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ñandú")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("pé@léa")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("Pingüino")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("henryⅣthrone")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ÑAndÚ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("péléa")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("ñandú")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
string("Pingüino")

View File

@@ -1 +0,0 @@
ñandú

View File

@@ -1 +0,0 @@
ÑAndÚ

View File

@@ -1 +0,0 @@
Pingüino

View File

@@ -1 +0,0 @@
pé@léa

View File

@@ -1 +0,0 @@
henryⅣ@throne

View File

@@ -3,6 +3,7 @@ package smtpsrv
import ( import (
"bufio" "bufio"
"net" "net"
"os"
"strings" "strings"
"testing" "testing"
@@ -15,7 +16,12 @@ import (
func TestSecLevel(t *testing.T) { func TestSecLevel(t *testing.T) {
// We can't simulate this externally because of the SPF record // We can't simulate this externally because of the SPF record
// requirement, so do a narrow test on Conn.secLevelCheck. // requirement, so do a narrow test on Conn.secLevelCheck.
dir := testlib.MustTempDir(t) // Create the directory by hand because we don't want to automatically
// chdir into it (it affects the fuzzing infrastructure).
dir, err := os.MkdirTemp("", "testlib_")
if err != nil {
t.Fatalf("Failed to create temp dir: %v\n", dir)
}
defer testlib.RemoveIfOk(t, dir) defer testlib.RemoveIfOk(t, dir)
dinfo, err := domaininfo.New(dir) dinfo, err := domaininfo.New(dir)

View File

@@ -1,280 +0,0 @@
// Fuzz testing for package smtpsrv. Based on server_test.
//go:build gofuzz
// +build gofuzz
package smtpsrv
import (
"bufio"
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"flag"
"fmt"
"io"
"math/big"
"net"
"net/textproto"
"os"
"strings"
"time"
"blitiri.com.ar/go/chasquid/internal/aliases"
"blitiri.com.ar/go/chasquid/internal/courier"
"blitiri.com.ar/go/chasquid/internal/testlib"
"blitiri.com.ar/go/chasquid/internal/userdb"
"blitiri.com.ar/go/log"
)
var (
// Server addresses. Will be filled in at init time.
smtpAddr = ""
submissionAddr = ""
submissionTLSAddr = ""
// TLS configuration to use in the clients.
// Will contain the generated server certificate as root CA.
tlsConfig *tls.Config
)
//
// === Fuzz test ===
//
func Fuzz(data []byte) int {
// Byte 0: mode
// The rest is what we will send the server, one line per command.
if len(data) < 1 {
return 0
}
var mode SocketMode
addr := ""
switch data[0] {
case '0':
mode = ModeSMTP
addr = smtpAddr
case '1':
mode = ModeSubmission
addr = submissionAddr
case '2':
mode = ModeSubmissionTLS
addr = submissionTLSAddr
default:
return 0
}
data = data[1:]
var err error
var conn net.Conn
if mode.TLS {
conn, err = tls.Dial("tcp", addr, tlsConfig)
} else {
conn, err = net.Dial("tcp", addr)
}
if err != nil {
panic(fmt.Errorf("failed to dial: %v", err))
}
defer conn.Close()
tconn := textproto.NewConn(conn)
defer tconn.Close()
scanner := bufio.NewScanner(bytes.NewBuffer(data))
for scanner.Scan() {
line := scanner.Text()
cmd := strings.TrimSpace(strings.ToUpper(line))
// Skip STARTTLS if it happens on a non-TLS connection - the jump is
// not going to happen via fuzzer, it will just cause a timeout (which
// is considered a crash).
if cmd == "STARTTLS" && !mode.TLS {
continue
}
if err = tconn.PrintfLine(line); err != nil {
break
}
if _, _, err = tconn.ReadResponse(-1); err != nil {
break
}
if cmd == "DATA" {
// We just sent DATA and got a response; send the contents.
err = exchangeData(scanner, tconn)
if err != nil {
break
}
}
}
if (err != nil && err != io.EOF) || scanner.Err() != nil {
return 1
}
return 0
}
func exchangeData(scanner *bufio.Scanner, tconn *textproto.Conn) error {
for scanner.Scan() {
line := scanner.Text()
if err := tconn.PrintfLine(line); err != nil {
return err
}
if line == "." {
break
}
}
// Read the "." response.
_, _, err := tconn.ReadResponse(-1)
return err
}
//
// === Test environment ===
//
// generateCert generates a new, INSECURE self-signed certificate and writes
// it to a pair of (cert.pem, key.pem) files to the given path.
// Note the certificate is only useful for testing purposes.
func generateCert(path string) error {
tmpl := x509.Certificate{
SerialNumber: big.NewInt(1234),
Subject: pkix.Name{
Organization: []string{"chasquid_test.go"},
},
DNSNames: []string{"localhost"},
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment |
x509.KeyUsageDigitalSignature |
x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
}
priv, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
return err
}
derBytes, err := x509.CreateCertificate(
rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv)
if err != nil {
return err
}
// Create a global config for convenience.
srvCert, err := x509.ParseCertificate(derBytes)
if err != nil {
return err
}
rootCAs := x509.NewCertPool()
rootCAs.AddCert(srvCert)
tlsConfig = &tls.Config{
ServerName: "localhost",
RootCAs: rootCAs,
}
certOut, err := os.Create(path + "/cert.pem")
if err != nil {
return err
}
defer certOut.Close()
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
keyOut, err := os.OpenFile(
path+"/key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer keyOut.Close()
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(priv),
}
pem.Encode(keyOut, block)
return nil
}
// waitForServer waits 10 seconds for the server to start, and returns an error
// if it fails to do so.
// It does this by repeatedly connecting to the address until it either
// replies or times out. Note we do not do any validation of the reply.
func waitForServer(addr string) {
start := time.Now()
for time.Since(start) < 10*time.Second {
conn, err := net.Dial("tcp", addr)
if err == nil {
conn.Close()
return
}
time.Sleep(100 * time.Millisecond)
}
panic(fmt.Errorf("%v not reachable", addr))
}
func init() {
flag.Parse()
log.Default.Level = log.Error
// Generate certificates in a temporary directory.
tmpDir, err := os.MkdirTemp("", "chasquid_smtpsrv_fuzz:")
if err != nil {
panic(fmt.Errorf("Failed to create temp dir: %v\n", tmpDir))
}
defer os.RemoveAll(tmpDir)
err = generateCert(tmpDir)
if err != nil {
panic(fmt.Errorf("Failed to generate cert for testing: %v\n", err))
}
smtpAddr = testlib.GetFreePort()
submissionAddr = testlib.GetFreePort()
submissionTLSAddr = testlib.GetFreePort()
s := NewServer()
s.Hostname = "localhost"
s.MaxDataSize = 50 * 1024 * 1025
s.AddCerts(tmpDir+"/cert.pem", tmpDir+"/key.pem")
s.AddAddr(smtpAddr, ModeSMTP)
s.AddAddr(submissionAddr, ModeSubmission)
s.AddAddr(submissionTLSAddr, ModeSubmissionTLS)
localC := &courier.MDA{}
remoteC := &courier.SMTP{}
s.InitQueue(tmpDir+"/queue", localC, remoteC)
s.InitDomainInfo(tmpDir + "/domaininfo")
udb := userdb.New("/dev/null")
udb.AddUser("testuser", "testpasswd")
s.aliasesR.AddAliasForTesting(
"to@localhost", "testuser@localhost", aliases.EMAIL)
s.AddDomain("localhost")
s.AddUserDB("localhost", udb)
// Disable SPF lookups, to avoid leaking DNS queries.
disableSPFForTesting = true
go s.ListenAndServe()
waitForServer(smtpAddr)
waitForServer(submissionAddr)
waitForServer(submissionTLSAddr)
}

View File

@@ -0,0 +1,96 @@
// Fuzz testing for package smtpsrv. Based on server_test.
package smtpsrv
import (
"bufio"
"bytes"
"crypto/tls"
"fmt"
"net"
"net/textproto"
"strings"
"testing"
)
func fuzzConnection(t *testing.T, modeI int, data []byte) {
var mode SocketMode
addr := ""
switch modeI {
case 0:
mode = ModeSMTP
addr = smtpAddr
case 1:
mode = ModeSubmission
addr = submissionAddr
case 2:
mode = ModeSubmissionTLS
addr = submissionTLSAddr
default:
mode = ModeSMTP
addr = smtpAddr
}
var err error
var conn net.Conn
if mode.TLS {
conn, err = tls.Dial("tcp", addr, tlsConfig)
} else {
conn, err = net.Dial("tcp", addr)
}
if err != nil {
panic(fmt.Errorf("failed to dial: %v", err))
}
defer conn.Close()
tconn := textproto.NewConn(conn)
defer tconn.Close()
scanner := bufio.NewScanner(bytes.NewBuffer(data))
for scanner.Scan() {
line := scanner.Text()
cmd := strings.TrimSpace(strings.ToUpper(line))
// Skip STARTTLS if it happens on a non-TLS connection - the jump is
// not going to happen via fuzzer, it will just cause a timeout (which
// is considered a crash).
if cmd == "STARTTLS" && !mode.TLS {
continue
}
if err = tconn.PrintfLine(line); err != nil {
break
}
if _, _, err = tconn.ReadResponse(-1); err != nil {
break
}
if cmd == "DATA" {
// We just sent DATA and got a response; send the contents.
err = exchangeData(scanner, tconn)
if err != nil {
break
}
}
}
}
func FuzzConnection(f *testing.F) {
f.Fuzz(fuzzConnection)
}
func exchangeData(scanner *bufio.Scanner, tconn *textproto.Conn) error {
for scanner.Scan() {
line := scanner.Text()
if err := tconn.PrintfLine(line); err != nil {
return err
}
if line == "." {
break
}
}
// Read the "." response.
_, _, err := tconn.ReadResponse(-1)
return err
}

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("HELO localhost\nMAIL FROM:<test@testy.com>\nRCPT LALA: <>\nRCPT TO:\nRCPT TO:<pepe>\nRCPT TO:<a@xn--->\nRCPT TO:<henryⅣ@testserver>\nRCPT TO:<aaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaX@bbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbX>\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("DATA\nHELO localhost\nDATA\nMAIL FROM:<a@b>\nRCPT TO: user@testserver\nDATA\nFrom: Mailer daemon <somewhere@horns.com>\nSubject: I've come to haunt you\nBad header\n\nMuahahahaha\n\n\n.\nQUIT\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("EHLO localhost\nMAIL FROM: <>\nRCPT TO: user@testserver\nDATA\nFrom: Mailer daemon <somewhere@báratro>\nSubject: I've come to haunt you\nMessage-ID: <booooo>\n\nÑañañañaña!\n\n\n.\nQUIT\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("HELO localhost\nMAIL LALA: <>\nMAIL FROM:\nMAIL FROM:<pepe>\nMAIL FROM:<a@xn--->\nMAIL FROM:<aaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaX@bbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbX>\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("HELO\nEHLO\nHELO localhost\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("HELO localhost\nQUIT\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("EHLO localhost\nMAIL FROM: <>\nRCPT TO: user@testserver\nDATA\nFrom: Mailer daemon <somewhere@horns.com>\nSubject: I've come to haunt you\n\nMuahahahaha\n\n\n.\nQUIT\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("EHLO localhost\nAUTH PLAIN something\nAUTH PLAIN something\nAUTH PLAIN something\nAUTH PLAIN something\nAUTH PLAIN something\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("EHLO localhost\nWHATISTHIS\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(0)
[]byte("EHLO localhost\nAUTH PLAIN\n")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
int(2)
[]byte("EHLO localhost\nAUTH SOMETHINGELSE\nAUTH PLAIN\ndXNlckB0ZXN0c2VydmVyAHlalala==\nAUTH PLAIN\ndXNlckB0ZXN0c2VydmVyAHVzZXJAdGVzdHNlcnZlcgB3cm9uZ3Bhc3N3b3Jk\nAUTH PLAIN\ndXNlckB0ZXN0c2VydmVyAHVzZXJAdGVzdHNlcnZlcgBzZWNyZXRwYXNzd29yZA==\nAUTH PLAIN\n")

View File

@@ -1,9 +0,0 @@
2EHLO localhost
AUTH SOMETHINGELSE
AUTH PLAIN
dXNlckB0ZXN0c2VydmVyAHlalala==
AUTH PLAIN
dXNlckB0ZXN0c2VydmVyAHVzZXJAdGVzdHNlcnZlcgB3cm9uZ3Bhc3N3b3Jk
AUTH PLAIN
dXNlckB0ZXN0c2VydmVyAHVzZXJAdGVzdHNlcnZlcgBzZWNyZXRwYXNzd29yZA==
AUTH PLAIN

View File

@@ -1,2 +0,0 @@
0EHLO localhost
AUTH PLAIN

View File

@@ -1,6 +0,0 @@
0EHLO localhost
AUTH PLAIN something
AUTH PLAIN something
AUTH PLAIN something
AUTH PLAIN something
AUTH PLAIN something

View File

@@ -1,15 +0,0 @@
0DATA
HELO localhost
DATA
MAIL FROM:<a@b>
RCPT TO: user@testserver
DATA
From: Mailer daemon <somewhere@horns.com>
Subject: I've come to haunt you
Bad header
Muahahahaha
.
QUIT

View File

@@ -1,6 +0,0 @@
0HELO localhost
MAIL LALA: <>
MAIL FROM:
MAIL FROM:<pepe>
MAIL FROM:<a@xn--->
MAIL FROM:<aaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaX@bbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbX>

View File

@@ -1,8 +0,0 @@
0HELO localhost
MAIL FROM:<test@testy.com>
RCPT LALA: <>
RCPT TO:
RCPT TO:<pepe>
RCPT TO:<a@xn--->
RCPT TO:<henryⅣ@testserver>
RCPT TO:<aaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaXaaaa5aaaaX@bbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbXbbbb5bbbbX>

View File

@@ -1,3 +0,0 @@
0HELO
EHLO
HELO localhost

View File

@@ -1,2 +0,0 @@
0HELO localhost
QUIT

View File

@@ -1,13 +0,0 @@
0EHLO localhost
MAIL FROM: <>
RCPT TO: user@testserver
DATA
From: Mailer daemon <somewhere@báratro>
Subject: I've come to haunt you
Message-ID: <booooo>
Ñañañañaña!
.
QUIT

View File

@@ -1,12 +0,0 @@
0EHLO localhost
MAIL FROM: <>
RCPT TO: user@testserver
DATA
From: Mailer daemon <somewhere@horns.com>
Subject: I've come to haunt you
Muahahahaha
.
QUIT

View File

@@ -1,2 +0,0 @@
0EHLO localhost
WHATISTHIS

View File

@@ -65,13 +65,11 @@ improvements on the main code paths.
## Fuzz tests ## Fuzz tests
Some Go packages also have instrumentation to run fuzz testing against them, Some Go packages also have instrumentation to run fuzz testing against them,
with the [go-fuzz](https://github.com/dvyukov/go-fuzz) tool. using the [Go native fuzzing support](https://go.dev/security/fuzz/).
This is critical for packages that handle sensitive user input, such as This is critical for packages that handle sensitive user input, such as
authentication encoding, aliases files, or username normalization. authentication encoding, aliases files, or username normalization.
They are implemented by a `fuzz.go` file within their respective Go packages.
## Command-line tool tests ## Command-line tool tests