Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mime/quotedprintable: single line with only period cause message truncation when used in SMTP DATA #61235

Open
shuLhan opened this issue Jul 8, 2023 · 3 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@shuLhan
Copy link
Contributor

shuLhan commented Jul 8, 2023

What version of Go are you using (go version)?

$ go version
go version devel go1.21-a618094c2a Sat Jul 8 13:45:19 2023 +0700 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE='on'
GOARCH='amd64'
GOBIN='/home/ms/go/bin'
GOCACHE='/home/ms/.cache/go-build'
GOENV='/home/ms/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/ms/go/pkg/mod'
GONOPROXY='git.sr.ht'
GONOSUMDB='git.sr.ht'
GOOS='linux'
GOPATH='/home/ms/go'
GOPRIVATE='git.sr.ht'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/ms/opt/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/ms/opt/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='devel go1.21-a618094c2a Sat Jul 8 13:45:19 2023 +0700'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='0'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build721925861=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Given the following example of message body,

A line that precisely have length 75 with . + LF will cause DATA truncation.\n
\n
Footer.\n

The quotedprintable Writer will encode the message into,

A line that precisely have length 75 with . + LF will cause DATA truncation=\r\n
.\r\n
\r\n
Footer.\r\n

If we pass the Writer output into SMTP DATA command, the server read the "\r\n.\r\n" as the end of DATA which cause the message truncated on the receiver.

Reproduceable code

package main

import (
"fmt"
"log"
"os"

"github.com/shuLhan/share/lib/email"
"github.com/shuLhan/share/lib/smtp"

)

func main() {
// Set up authentication information.
var (
smtpUser = os.Getenv(SMTP_USER)
smtpPass = os.Getenv(SMTP_PASS)
smtpServer = os.Getenv(SMTP_SERVER)
smtpServerPort = os.Getenv(SMTP_SERVER_PORT)
from = os.Getenv(SMTP_FROM)
to = os.Getenv(SMTP_TO)
)

fmt.Printf("SMTP user: %s\n", smtpUser)
fmt.Printf("SMTP pass: %s\n", smtpPass)
fmt.Printf("SMTP addr: %s:%s\n", smtpServer, smtpServerPort)
fmt.Printf("From     : %s\n", from)
fmt.Printf("To       : %s\n", to)

var (
	subject  = `Truncated message`
	bodyText = "A line that precisely have length 75 with . + LF will cause DATA truncation.\n" +
		"\n" +
		"This line will not be received.\n"

	msg    email.Message
	mailtx *smtp.MailTx
	data   []byte
	err    error
)

err = msg.SetFrom(from)
if err != nil {
	log.Fatal(err)
}
err = msg.SetTo(to)
if err != nil {
	log.Fatal(err)
}
msg.SetSubject(subject)
err = msg.SetBodyText([]byte(bodyText))
if err != nil {
	log.Fatal(err)
}
data, err = msg.Pack()
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Data: %s\n", data)

mailtx = smtp.NewMailTx(from, []string{to}, data)

var (
	clientOpts = smtp.ClientOptions{
		ServerUrl:     fmt.Sprintf(`smtps://%s:%s`, smtpServer, smtpServerPort),
		AuthUser:      smtpUser,
		AuthPass:      smtpPass,
		AuthMechanism: smtp.SaslMechanismPlain,
	}
	cl *smtp.Client
)

cl, err = smtp.NewClient(clientOpts)
if err != nil {
	log.Fatal(err)
}

res, err := cl.MailTx(mailtx)
if err != nil {
	log.Fatal(`MailTx:`, err)
}

log.Printf(`MailTx: response: %+v`, res)

_, err = cl.Quit()
if err != nil {
	log.Fatal(err)
}

}

What did you expect to see?

Full message received as,

from: <redacted>
to: <redacted>
subject: Truncated message
date: Sat, 8 Jul 2023 16:47:43 +0700
message-id: <1688809663.1vIVqALM@inspiro>
mime-version: 1.0
content-type: text/plain; charset="utf-8"
content-transfer-encoding: quoted-printable

A line that precisely have length 75 with . + LF will cause DATA truncation=
=2E

This line will not be received.

What did you see instead?

Message received as,

from: <redacted>
to: <redacted>
subject: Truncated message
date: Sat, 8 Jul 2023 16:38:41 +0700
message-id: <1688809121.Iz9VWWN7@inspiro>
mime-version: 1.0
content-type: text/plain; charset="utf-8"
content-transfer-encoding: quoted-printable

A line that precisely have length 75 with . + LF will cause DATA truncation=

@gopherbot
Copy link

Change https://go.dev/cl/508535 mentions this issue: mime/quotedprintable: fix encoding where a period alone on a line

@seankhliao seankhliao added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jul 9, 2023
@neild
Copy link
Contributor

neild commented Jul 25, 2023

If we pass the Writer output into SMTP DATA command, the server read the "\r\n.\r\n" as the end of DATA which cause the message truncated on the receiver.

A line starting with a . needs to be sent to the SMTP DATA command prefixed with an additional .:
https://datatracker.ietf.org/doc/html/rfc5321#section-4.5.2

Perhaps we should change the mime/quotedprintable behavior, but the problem of message truncation here lies in the SMTP client implementation.

@shuLhan
Copy link
Contributor Author

shuLhan commented Jul 25, 2023

@neild Thanks for reviewing.

... but the problem of message truncation here lies in the SMTP client implementation.

You were right. I have tested with net/smtp Client and it works perfectly.

Perhaps we should change the mime/quotedprintable behavior

I read your comment on gerrit, will continue discussion in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants