git » chasquid » commit 3eac221

chasquid: Make the "Received:" header RFC compliant

author Alberto Bertogli
2016-10-08 17:38:54 UTC
committer Alberto Bertogli
2016-10-09 23:51:05 UTC
parent bc2b3b40a545f8ddbdb515c5827ba7aa5032ec74

chasquid: Make the "Received:" header RFC compliant

The Received header has some predefined structure and valid keywords,
this patch adjust how we create them to be compliant with that
structure.

chasquid.go +14 -6
test/t-05-null_address/expected_dsr +4 -3

diff --git a/chasquid.go b/chasquid.go
index 16fb926..c12ff2f 100644
--- a/chasquid.go
+++ b/chasquid.go
@@ -807,19 +807,26 @@ func (c *Conn) DATA(params string) (code int, msg string) {
 func (c *Conn) addReceivedHeader() {
 	var v string
 
+	// Format is semi-structured, defined by
+	// https://tools.ietf.org/html/rfc5321#section-4.4
+
 	if c.completedAuth {
-		v += fmt.Sprintf("from user %s@%s\n", c.authUser, c.authDomain)
+		v += fmt.Sprintf("from %s (authenticated as %s@%s)\n",
+			envelope.DomainOf(c.mailFrom), c.authUser, c.authDomain)
 	} else {
-		v += fmt.Sprintf("from %s\n", c.netconn.RemoteAddr().String())
+		v += fmt.Sprintf("from %s (%s)\n",
+			envelope.DomainOf(c.mailFrom), c.netconn.RemoteAddr().String())
 	}
 
-	v += fmt.Sprintf("by %s (chasquid SMTP) over ", c.hostname)
+	v += fmt.Sprintf("by %s (chasquid)\n", c.hostname)
+
+	v += "(over "
 	if c.tlsConnState != nil {
-		v += fmt.Sprintf("%s (%s)\n",
+		v += fmt.Sprintf("%s-%s)\n",
 			tlsconst.VersionName(c.tlsConnState.Version),
 			tlsconst.CipherSuiteName(c.tlsConnState.CipherSuite))
 	} else {
-		v += "plain text!\n"
+		v += "plain text!)\n"
 	}
 
 	// Note we must NOT include c.rcptTo, that would leak BCCs.
@@ -829,7 +836,7 @@ func (c *Conn) addReceivedHeader() {
 	// The ";" is a mandatory separator. The date format is not standard but
 	// this one seems to be widely used.
 	// https://tools.ietf.org/html/rfc5322#section-3.6.7
-	v += fmt.Sprintf("on ; %s\n", time.Now().Format(time.RFC1123Z))
+	v += fmt.Sprintf("; %s\n", time.Now().Format(time.RFC1123Z))
 	c.data = envelope.AddHeader(c.data, "Received", v)
 
 	if c.spfResult != "" {
@@ -850,6 +857,7 @@ func checkData(data []byte) error {
 
 	// This serves as a basic form of loop prevention. It's not infallible but
 	// should catch most instances of accidental looping.
+	// https://tools.ietf.org/html/rfc5321#section-6.3
 	if len(msg.Header["Received"]) > 50 {
 		loopsDetected.Add(1)
 		return fmt.Errorf("email passed through more than 50 MTAs, looping?")
diff --git a/test/t-05-null_address/expected_dsr b/test/t-05-null_address/expected_dsr
index b2c473b..080ac89 100644
--- a/test/t-05-null_address/expected_dsr
+++ b/test/t-05-null_address/expected_dsr
@@ -20,10 +20,11 @@ Delivery to the following recipient(s) failed permanently:
 
 ----- Original message -----
 
-Received: from user user@testserver
-	by *
+Received: from testserver (authenticated as user@testserver)
+	by testserver (chasquid)
+	(over *
 	(envelope from "user@testserver")
-	on ; *
+	; *
 Date: *
 From: Mailer daemon <somewhere@horns.com>
 Subject: I've come to haunt you