reject attempts at starttls for smtp & imap when no tls config is present

we didn't announce starttls as capability, but clients can still try them. we
would try to do a handshake with a nil certificate, which would cause a
goroutine panic (which is handled gracefully, shutting down the connection).

found with code that was doing starttls unconditionally.
This commit is contained in:
Mechiel Lukkien 2024-09-15 17:18:50 +02:00
parent 0977b7a6d3
commit a7bdc41cd4
No known key found for this signature in database
2 changed files with 6 additions and 0 deletions

View file

@ -1454,6 +1454,9 @@ func (c *conn) cmdStarttls(tag, cmd string, p *parser) {
if c.tls { if c.tls {
xsyntaxErrorf("tls already active") // ../rfc/9051:1353 xsyntaxErrorf("tls already active") // ../rfc/9051:1353
} }
if c.tlsConfig == nil {
xsyntaxErrorf("starttls not announced")
}
conn := c.conn conn := c.conn
if n := c.br.Buffered(); n > 0 { if n := c.br.Buffered(); n > 0 {

View file

@ -931,6 +931,9 @@ func (c *conn) cmdStarttls(p *parser) {
if c.account != nil { if c.account != nil {
xsmtpUserErrorf(smtp.C503BadCmdSeq, smtp.SeProto5BadCmdOrSeq1, "cannot starttls after authentication") xsmtpUserErrorf(smtp.C503BadCmdSeq, smtp.SeProto5BadCmdOrSeq1, "cannot starttls after authentication")
} }
if c.tlsConfig == nil {
xsmtpUserErrorf(smtp.C503BadCmdSeq, smtp.SeProto5BadCmdOrSeq1, "starttls not offered")
}
// We don't want to do TLS on top of c.r because it also prints protocol traces: We // We don't want to do TLS on top of c.r because it also prints protocol traces: We
// don't want to log the TLS stream. So we'll do TLS on the underlying connection, // don't want to log the TLS stream. So we'll do TLS on the underlying connection,