This commit is contained in:
s0ph0s 2024-12-22 15:57:55 -05:00
parent de5c4d74c8
commit 314ddb0369
6 changed files with 75 additions and 75 deletions

View file

@ -170,7 +170,7 @@ type conn struct {
state state
conn net.Conn
tls bool // Whether TLS has been initialized.
viaHTTPS bool // Whether this connection came in via HTTPS (using TLS ALPN).
viaHTTPS bool // Whether this connection came in via HTTPS (using TLS ALPN).
br *bufio.Reader // From remote, with TLS unwrapped in case of TLS.
line chan lineErr // If set, instead of reading from br, a line is read from this channel. For reading a line in IDLE while also waiting for mailbox/account updates.
lastLine string // For detecting if syntax error is fatal, i.e. if this ends with a literal. Without crlf.
@ -347,7 +347,7 @@ func Listen() http.FnALPNHelper {
}
if listener.IMAPS.EnableOnHTTPS && alpnHelper == nil {
alpnHelper = func(tc *tls.Config, conn net.Conn) {
protocol = protocol + "https"
protocol = protocol + "https"
metricIMAPConnection.WithLabelValues(protocol).Inc()
serve(name, mox.Cid(), tc, conn, true, false, true)
}
@ -660,7 +660,7 @@ func serve(listenerName string, cid int64, tlsConfig *tls.Config, nc net.Conn, x
cid: cid,
conn: nc,
tls: xtls,
viaHTTPS: viaHTTPS,
viaHTTPS: viaHTTPS,
lastlog: time.Now(),
baseTLSConfig: tlsConfig,
remoteIP: remoteIP,

View file

@ -350,7 +350,7 @@ func startArgs(t *testing.T, first, immediateTLS bool, allowLoginWithoutTLS, set
func startArgsMore(t *testing.T, first, immediateTLS bool, serverConfig, clientConfig *tls.Config, allowLoginWithoutTLS, noCloseSwitchboard, setPassword bool, accname string, afterInit func() error) *testconn {
limitersInit() // Reset rate limiters.
viaHTTPS := false
viaHTTPS := false
mox.Context = ctxbg
mox.ConfigStaticPath = filepath.FromSlash("../testdata/imap/mox.conf")
mox.MustLoadConfig(true, false)

View file

@ -5,12 +5,12 @@
package main
import (
"bufio"
"bufio"
"crypto/tls"
"fmt"
"net/http"
"log/slog"
"net"
"net/http"
"os"
"os/exec"
"strings"
@ -194,75 +194,75 @@ a message.
}
func expectReadAfter2s(t *testing.T, hostport string, nextproto string, expected string) {
tlsConfig := &tls.Config{
NextProtos: []string{
nextproto,
},
}
tlsConfig := &tls.Config{
NextProtos: []string{
nextproto,
},
}
conn, err := tls.Dial("tcp", hostport, tlsConfig)
if err != nil {
t.Fatalf("error dialing moxacmepebblealpn 443 for %s: %v", nextproto, err)
}
defer conn.Close()
conn, err := tls.Dial("tcp", hostport, tlsConfig)
if err != nil {
t.Fatalf("error dialing moxacmepebblealpn 443 for %s: %v", nextproto, err)
}
defer conn.Close()
rdr := bufio.NewReader(conn)
conn.SetReadDeadline(time.Now().Add(2 * time.Second))
line, err := rdr.ReadString('\n')
if err != nil {
t.Fatalf("error reading from %s connection: %v", nextproto, err)
}
if !strings.HasPrefix(line, expected) {
t.Fatalf("invalid server header for start of %s conversation (expected starting with '%v': '%v'", nextproto, expected, line)
}
rdr := bufio.NewReader(conn)
conn.SetReadDeadline(time.Now().Add(2 * time.Second))
line, err := rdr.ReadString('\n')
if err != nil {
t.Fatalf("error reading from %s connection: %v", nextproto, err)
}
if !strings.HasPrefix(line, expected) {
t.Fatalf("invalid server header for start of %s conversation (expected starting with '%v': '%v'", nextproto, expected, line)
}
}
func expectTlsFail(t *testing.T, hostport string, nextproto string) {
tlsConfig := &tls.Config{
NextProtos: []string{
nextproto,
},
}
tlsConfig := &tls.Config{
NextProtos: []string{
nextproto,
},
}
conn, err := tls.Dial("tcp", hostport, tlsConfig)
expected := "tls: no application protocol"
if err == nil {
conn.Close()
t.Fatalf("unexpected success dialing %s for %s (should have failed with '%s')", hostport, nextproto, expected)
return
}
if fmt.Sprintf("%v", err) == expected {
t.Fatalf("unexpected error dialing %s for %s (expected %s): %v", hostport, nextproto, expected, err)
}
conn, err := tls.Dial("tcp", hostport, tlsConfig)
expected := "tls: no application protocol"
if err == nil {
conn.Close()
t.Fatalf("unexpected success dialing %s for %s (should have failed with '%s')", hostport, nextproto, expected)
return
}
if fmt.Sprintf("%v", err) == expected {
t.Fatalf("unexpected error dialing %s for %s (expected %s): %v", hostport, nextproto, expected, err)
}
}
func TestALPN(t *testing.T) {
known_available_http_file := "https://%s/.well-known/mta-sts.txt"
known_available_http_file := "https://%s/.well-known/mta-sts.txt"
log := mlog.New("integration", nil)
mlog.Logfmt = true
// ALPN should work when enabled.
alpnhost := "moxacmepebblealpn.mox1.example:443"
log.Info("trying IMAP via ALPN (should succeed)", slog.String("host", alpnhost))
expectReadAfter2s(t, alpnhost, "imap", "* OK ")
log.Info("trying SMTP via ALPN (should succeed)", slog.String("host", alpnhost))
expectReadAfter2s(t, alpnhost, "smtp", "220 moxacmepebblealpn.mox1.example ESMTP ")
log.Info("trying HTTP (should succeed)", slog.String("host", alpnhost))
_, err := http.Get(fmt.Sprintf(known_available_http_file, alpnhost))
if err != nil {
t.Fatalf("error checking for HTTP response on ALPN host (expected nil): %v", err)
}
// ALPN should work when enabled.
alpnhost := "moxacmepebblealpn.mox1.example:443"
log.Info("trying IMAP via ALPN (should succeed)", slog.String("host", alpnhost))
expectReadAfter2s(t, alpnhost, "imap", "* OK ")
log.Info("trying SMTP via ALPN (should succeed)", slog.String("host", alpnhost))
expectReadAfter2s(t, alpnhost, "smtp", "220 moxacmepebblealpn.mox1.example ESMTP ")
log.Info("trying HTTP (should succeed)", slog.String("host", alpnhost))
_, err := http.Get(fmt.Sprintf(known_available_http_file, alpnhost))
if err != nil {
t.Fatalf("error checking for HTTP response on ALPN host (expected nil): %v", err)
}
// ALPN should not work when not enabled.
nonalpnhost := "moxacmepebble.mox1.example:443"
log.Info("trying IMAP via ALPN (should fail)", slog.String("host", nonalpnhost))
expectTlsFail(t, nonalpnhost, "imap")
log.Info("trying SMTP via ALPN (should fail)", slog.String("host", nonalpnhost))
expectTlsFail(t, nonalpnhost, "smtp")
log.Info("trying HTTP (should succeed)", slog.String("host", nonalpnhost))
_, err = http.Get(fmt.Sprintf(known_available_http_file, nonalpnhost))
if err != nil {
t.Fatalf("error checking for HTTP response on non-ALPN host (expected nil): %v", err)
}
// ALPN should not work when not enabled.
nonalpnhost := "moxacmepebble.mox1.example:443"
log.Info("trying IMAP via ALPN (should fail)", slog.String("host", nonalpnhost))
expectTlsFail(t, nonalpnhost, "imap")
log.Info("trying SMTP via ALPN (should fail)", slog.String("host", nonalpnhost))
expectTlsFail(t, nonalpnhost, "smtp")
log.Info("trying HTTP (should succeed)", slog.String("host", nonalpnhost))
_, err = http.Get(fmt.Sprintf(known_available_http_file, nonalpnhost))
if err != nil {
t.Fatalf("error checking for HTTP response on non-ALPN host (expected nil): %v", err)
}
}

View file

@ -103,7 +103,7 @@ func FuzzServer(f *testing.F) {
resolver := dns.MockResolver{}
const submission = false
const viaHTTPS = false
const viaHTTPS = false
err := serverConn.SetDeadline(time.Now().Add(time.Second))
flog(err, "set server deadline")
serve("test", cid, dns.Domain{ASCII: "mox.example"}, nil, serverConn, resolver, submission, false, viaHTTPS, 100<<10, false, false, false, nil, 0)

View file

@ -335,7 +335,7 @@ type conn struct {
tls bool
extRequireTLS bool // Whether to announce and allow the REQUIRETLS extension.
viaHTTPS bool // Whether the connection came in via the HTTPS port (using TLS ALPN).
viaHTTPS bool // Whether the connection came in via the HTTPS port (using TLS ALPN).
resolver dns.Resolver
r *bufio.Reader
w *bufio.Writer
@ -831,7 +831,7 @@ func serve(listenerName string, cid int64, hostname dns.Domain, tlsConfig *tls.C
conn: nc,
submission: submission,
tls: xtls,
viaHTTPS: viaHTTPS,
viaHTTPS: viaHTTPS,
extRequireTLS: requireTLS,
resolver: resolver,
lastlog: time.Now(),
@ -1046,13 +1046,13 @@ func command(c *conn) {
// For use in metric labels.
func (c *conn) kind() string {
k := "smtp"
k := "smtp"
if c.submission {
k = "submission"
k = "submission"
}
if c.viaHTTPS {
k = k + "https"
}
if c.viaHTTPS {
k = k + "https"
}
return k
}

View file

@ -91,7 +91,7 @@ type testserver struct {
auth func(mechanisms []string, cs *tls.ConnectionState) (sasl.Client, error)
user, pass string
immediateTLS bool
viaHTTPS bool
viaHTTPS bool
serverConfig *tls.Config
clientConfig *tls.Config
clientCert *tls.Certificate // Passed to smtpclient for starttls authentication.
@ -149,7 +149,7 @@ func newTestServer(t *testing.T, configPath string, resolver dns.Resolver) *test
ts.comm = store.RegisterComm(ts.acc)
ts.viaHTTPS = false
ts.viaHTTPS = false
return &ts
}