Skip to content

Commit

Permalink
fix: do STARTTLS upgrade if available (#57)
Browse files Browse the repository at this point in the history
* fix: do STARTTLS upgrade if available

Replace the missing STARTTLS upgrade call.

Fixes #56 (thanks @Top-Ranger!)

* chore: disable gosec MinVersion lint for STARTTLS

Realistically STARTTLS is insecure in the first place, so there's no real harm
here - any attacker would simply prevent the STARTTLS extension from being
advertised rather than trying to downgrade the protocol.
  • Loading branch information
domodwyer authored Dec 3, 2020
1 parent ccbef99 commit 78f7fef
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
15 changes: 14 additions & 1 deletion sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package mailyak

import (
"bufio"
"crypto/tls"
"io"
"net"
"net/smtp"
Expand Down Expand Up @@ -37,14 +38,26 @@ type sendableMail interface {
// conn.
//
// serverName must be the hostname (or IP address) of the remote endpoint.
func smtpExchange(m sendableMail, conn net.Conn, serverName string) error {
func smtpExchange(m sendableMail, conn net.Conn, serverName string, tryTLSUpgrade bool) error {
// Connect to the SMTP server
c, err := smtp.NewClient(conn, serverName)
if err != nil {
return err
}
defer func() { _ = c.Quit() }()

if tryTLSUpgrade {
if ok, _ := c.Extension("STARTTLS"); ok {
//nolint:gosec
config := &tls.Config{
ServerName: serverName,
}
if err = c.StartTLS(config); err != nil {
return err
}
}
}

// Attempt to authenticate if credentials were provided
var nilAuth smtp.Auth
if auth := m.getAuth(); auth != nilAuth {
Expand Down
2 changes: 1 addition & 1 deletion sender_explicit_tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (s *senderExplicitTLS) Send(m sendableMail) error {

// Perform the SMTP protocol conversation, using the provided TLS ServerName
// as the SMTP server name.
return smtpExchange(m, conn, s.hostname)
return smtpExchange(m, conn, s.hostname, false)
}

// newSenderWithExplicitTLS constructs a new senderExplicitTLS.
Expand Down
2 changes: 1 addition & 1 deletion sender_starttls.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (s *senderWithStartTLS) Send(m sendableMail) error {
}
defer func() { _ = conn.Close() }()

return smtpExchange(m, conn, s.hostname)
return smtpExchange(m, conn, s.hostname, true)
}

func newSenderWithStartTLS(hostAndPort string) *senderWithStartTLS {
Expand Down

0 comments on commit 78f7fef

Please sign in to comment.