~sircmpwn/aerc

do not check for STARTTLS support for localhost v1 PROPOSED

Paul Vixie
Paul Vixie: 1
 do not check for STARTTLS support for localhost

 1 files changed, 31 insertions(+), 22 deletions(-)
Paul Vixie
> > ...
> 
> So, correct me if I am wrong. You have a (presumably publically
> available) mailserver, which is secured by STARTTLS.
STARTTLS is available, yes. not everything i have speaking to that
mail server uses that option.
> Now you wish to
> access it via the loopback address, because you're either on the same
> device or have it forwarded. Is that correct so far?
except the "now" part, yes. i have a lot of things pointed at
localhost:25 or localhost:587. this is more convenient for me
than rewriting software to reach it on a UNIX domain socket,
and i prefer not to pipe to "sendmail" because i can't get
recipient by recipient error reporting that way.
Next
Please refer to this tutorial on how to properly submit patches:
https://git-send-email.io/#step-4

Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/aerc/patches/24739/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH] do not check for STARTTLS support for localhost Export this patch

Paul Vixie
---
 commands/compose/send.go | 53 +++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/commands/compose/send.go b/commands/compose/send.go
index 849182d..34e9fd9 100644
--- a/commands/compose/send.go
+++ b/commands/compose/send.go
@@ -360,7 +360,7 @@ func newSmtpSender(ctx sendCtx) (io.WriteCloser, error) {
func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
	serverName := host
	if !strings.ContainsRune(host, ':') {
		host = host + ":587" // Default to submission port
		host += ":587" // Default to submission port
	} else {
		serverName = host[:strings.IndexRune(host, ':')]
	}
@@ -368,27 +368,36 @@ func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
	if err != nil {
		return nil, errors.Wrap(err, "smtp.Dial")
	}
	if sup, _ := conn.Extension("STARTTLS"); sup {
		if !starttls {
			err := errors.New("STARTTLS is supported by this server, " +
				"but not set in accounts.conf. " +
				"Add smtp-starttls=yes")
			conn.Close()
			return nil, err
		}
		if err = conn.StartTLS(&tls.Config{
			ServerName: serverName,
		}); err != nil {
			conn.Close()
			return nil, errors.Wrap(err, "StartTLS")
		}
	} else {
		if starttls {
			err := errors.New("STARTTLS requested, but not supported " +
				"by this SMTP server. Is someone tampering with your " +
				"connection?")
			conn.Close()
			return nil, err
	localhost := serverName == `localhost` ||
		serverName == `127.0.0.1` ||
		serverName == `127.1` ||
		serverName == `::1`
	if !localhost {
		if sup, _ := conn.Extension("STARTTLS"); sup {
			if !starttls {
				err := errors.New("STARTTLS is supported " +
					"by this non-localhost SMTP server, " +
					"but not requested in accounts.conf. " +
					"Add smtp-starttls=yes")
				conn.Close()
				return nil, err
			}
			if err = conn.StartTLS(&tls.Config{
				ServerName: serverName,
			}); err != nil {
				conn.Close()
				return nil, errors.Wrap(err, "StartTLS")
			}
		} else {
			if starttls {
				err := errors.New("STARTTLS requested " +
					"in accounts.conf, but not supported " +
					"by this non-localhost SMTP server. " +
					"Is someone tampering with your " +
					"connection?")
				conn.Close()
				return nil, err
			}
		}
	}
	return conn, nil
-- 
2.32.0
I don't really understand why you'd want this - what's your usecase? Why
can't you just disable STARTTLS on your local SMTP server?

Regardless, it's worth noting that all of 127.0.0.0/8 is reserved for
loopback and that other hostnames could resolve to that block. A more
robust solution would resolve the server name then use
net.IP.IsLoopback() to see if it's a loopback address.
Paul Vixie
thanks to all for your feedback. i've removed the string comparisons.

if this is unobjectiionable, i'll send an updated patch against origin/master.
the patch below is relative to the patch i sent previously.

comments and questions welcome, as before.

vixie

re:

--- a/commands/compose/send.go
+++ b/commands/compose/send.go
@@ -5,6 +5,7 @@ import (
 	"crypto/tls"
 	"fmt"
 	"io"
+	"net"
 	"net/url"
 	"os/exec"
 	"strings"
@@ -368,10 +369,16 @@ func connectSmtp(starttls bool, host string) (*smtp.Client, error) {
 	if err != nil {
 		return nil, errors.Wrap(err, "smtp.Dial")
 	}
-	localhost := serverName == `localhost` ||
-		serverName == `127.0.0.1` ||
-		serverName == `127.1` ||
-		serverName == `::1`
+	// no way to get the chosen ip out of the smtp.conn; repeat DNS request
+	var localhost bool
+	if ips, err := net.LookupIP(serverName); err == nil {
+		for _, ip := range ips {
+			if ip.IsLoopback() {
+				localhost = true
+				break
+			}
+		}
+	}
 	if !localhost {
 		if sup, _ := conn.Extension("STARTTLS"); sup {
 			if !starttls {