mirror of
https://blitiri.com.ar/repos/chasquid
synced 2026-01-08 17:51:57 +00:00
test: Improve DATA handling in the smtpsrv fuzzer
The smtpsrv fuzzer doesn't handle DATA commands particularly well: it will continue to read but will skip lines that have STARTTLS as content, and only really care for the first line due to a bug. This patch fixes the handling, and moves the logic to a separate function for readability.
This commit is contained in:
@@ -85,34 +85,33 @@ func Fuzz(data []byte) int {
|
|||||||
tconn := textproto.NewConn(conn)
|
tconn := textproto.NewConn(conn)
|
||||||
defer tconn.Close()
|
defer tconn.Close()
|
||||||
|
|
||||||
in_data := false
|
|
||||||
scanner := bufio.NewScanner(bytes.NewBuffer(data))
|
scanner := bufio.NewScanner(bytes.NewBuffer(data))
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
cmd := strings.TrimSpace(strings.ToUpper(line))
|
||||||
|
|
||||||
// Skip STARTTLS if it happens on a non-TLS connection - the jump is
|
// 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
|
// not going to happen via fuzzer, it will just cause a timeout (which
|
||||||
// is considered a crash).
|
// is considered a crash).
|
||||||
if strings.TrimSpace(strings.ToUpper(line)) == "STARTTLS" && !mode.TLS {
|
if cmd == "STARTTLS" && !mode.TLS {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = tconn.PrintfLine(line); err != nil {
|
if err = tconn.PrintfLine(line); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if in_data {
|
|
||||||
if line == "." {
|
|
||||||
in_data = false
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err = tconn.ReadResponse(-1); err != nil {
|
if _, _, err = tconn.ReadResponse(-1); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
in_data = strings.HasPrefix(strings.ToUpper(line), "DATA")
|
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 {
|
if (err != nil && err != io.EOF) || scanner.Err() != nil {
|
||||||
return 1
|
return 1
|
||||||
@@ -121,6 +120,22 @@ func Fuzz(data []byte) int {
|
|||||||
return 0
|
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 ===
|
// === Test environment ===
|
||||||
//
|
//
|
||||||
@@ -216,7 +231,7 @@ func waitForServer(addr string) {
|
|||||||
func init() {
|
func init() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
log.Default.Level = log.Debug
|
log.Default.Level = log.Error
|
||||||
|
|
||||||
// Generate certificates in a temporary directory.
|
// Generate certificates in a temporary directory.
|
||||||
tmpDir, err := ioutil.TempDir("", "chasquid_smtpsrv_fuzz:")
|
tmpDir, err := ioutil.TempDir("", "chasquid_smtpsrv_fuzz:")
|
||||||
|
|||||||
Reference in New Issue
Block a user