From 8f1f943fca1368532be8ee876442db2de1dc676d Mon Sep 17 00:00:00 2001 From: Alberto Bertogli Date: Fri, 25 Jun 2021 12:09:56 +0100 Subject: [PATCH] mda-lmtp: Add -to_puny, to punycode-encode addresses Some LMTP servers (like dovecot) can't handle UTF8 addresses in the LMTP commands. This can be problematic if we want to use them with UTF8 domains or usernames, which are well supported by chasquid. To help workaround this issue, this patch adds a new -to_puny flag for mda-lmtp, that makes it encode `from` and `recipient` in punycode. That way, the server will get punycode-encoded (ASCII) strings in the LTMP commands. This can be particularly convenient when the recipients are ASCII (because they're under the mail server control), but `from` may not be (because it comes from the network). --- cmd/mda-lmtp/mda-lmtp.go | 25 ++++++++++++++++++++-- cmd/mda-lmtp/test_puny_ascii.cmy | 33 ++++++++++++++++++++++++++++++ cmd/mda-lmtp/test_puny_invalid.cmy | 9 ++++++++ cmd/mda-lmtp/test_puny_utf8.cmy | 33 ++++++++++++++++++++++++++++++ cmd/mda-lmtp/test_utf8.cmy | 33 ++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 cmd/mda-lmtp/test_puny_ascii.cmy create mode 100644 cmd/mda-lmtp/test_puny_invalid.cmy create mode 100644 cmd/mda-lmtp/test_puny_utf8.cmy create mode 100644 cmd/mda-lmtp/test_utf8.cmy diff --git a/cmd/mda-lmtp/mda-lmtp.go b/cmd/mda-lmtp/mda-lmtp.go index 8be8bfa..5c1a699 100644 --- a/cmd/mda-lmtp/mda-lmtp.go +++ b/cmd/mda-lmtp/mda-lmtp.go @@ -14,6 +14,8 @@ import ( "net/textproto" "os" "strings" + + "golang.org/x/net/idna" ) // Command-line flags @@ -24,6 +26,9 @@ var ( addrNetwork = flag.String("addr_network", "", "Network of the LMTP address (e.g. unix or tcp)") addr = flag.String("addr", "", "LMTP server address") + + toPuny = flag.Bool("to_puny", false, + "Encode addresses using punycode") ) func usage() { @@ -51,13 +56,29 @@ func tempExit(format string, args ...interface{}) { os.Exit(75) } +func permExit(format string, args ...interface{}) { + fmt.Printf(format+"\n", args...) + os.Exit(2) +} + func main() { + var err error flag.Usage = usage flag.Parse() if *addr == "" { - fmt.Printf("No LMTP server address given (use --addr)\n") - os.Exit(2) + permExit("No LMTP server address given (use --addr)") + } + + if *toPuny { + *fromwhom, err = idna.ToASCII(*fromwhom) + if err != nil { + permExit("cannot puny-encode from: %v", err) + } + *recipient, err = idna.ToASCII(*recipient) + if err != nil { + permExit("cannot puny-encode recipient: %v", err) + } } // Try to autodetect the network if it's missing. diff --git a/cmd/mda-lmtp/test_puny_ascii.cmy b/cmd/mda-lmtp/test_puny_ascii.cmy new file mode 100644 index 0000000..9998e6c --- /dev/null +++ b/cmd/mda-lmtp/test_puny_ascii.cmy @@ -0,0 +1,33 @@ + +nc unix_listen .test-sock + +mda |= ./mda-lmtp --addr=.test-sock --addr_network=unix \ + -to_puny -f from -d to < test-email + +nc -> 220 Hola desde expect + +nc <~ LHLO .* +nc -> 250-Bienvenido! +nc -> 250 Contame... + +nc <- MAIL FROM: +nc -> 250 Aja + +nc <- RCPT TO: +nc -> 250 Aja + +nc <- DATA +nc -> 354 Dale + +nc <- Subject: test +nc <- +nc <- This is a test. +nc <- . + +nc -> 250 Recibido + +nc <- QUIT +nc -> 221 Chauchas + +mda wait 0 + diff --git a/cmd/mda-lmtp/test_puny_invalid.cmy b/cmd/mda-lmtp/test_puny_invalid.cmy new file mode 100644 index 0000000..9c63706 --- /dev/null +++ b/cmd/mda-lmtp/test_puny_invalid.cmy @@ -0,0 +1,9 @@ +mda = ./mda-lmtp --addr=.test-sock --addr_network=unix \ + -to_puny -f fröm -d xn--t < test-email +mda <- cannot puny-encode recipient: idna: invalid label "t" +mda wait 2 + +mda = ./mda-lmtp --addr=.test-sock --addr_network=unix \ + -to_puny -f xn--f -d to < test-email +mda <- cannot puny-encode from: idna: invalid label "f" +mda wait 2 diff --git a/cmd/mda-lmtp/test_puny_utf8.cmy b/cmd/mda-lmtp/test_puny_utf8.cmy new file mode 100644 index 0000000..852aa4f --- /dev/null +++ b/cmd/mda-lmtp/test_puny_utf8.cmy @@ -0,0 +1,33 @@ + +nc unix_listen .test-sock + +mda |= ./mda-lmtp --addr=.test-sock --addr_network=unix \ + -to_puny -f fröm -d þo < test-email + +nc -> 220 Hola desde expect + +nc <~ LHLO .* +nc -> 250-Bienvenido! +nc -> 250 Contame... + +nc <- MAIL FROM: +nc -> 250 Aja + +nc <- RCPT TO: +nc -> 250 Aja + +nc <- DATA +nc -> 354 Dale + +nc <- Subject: test +nc <- +nc <- This is a test. +nc <- . + +nc -> 250 Recibido + +nc <- QUIT +nc -> 221 Chauchas + +mda wait 0 + diff --git a/cmd/mda-lmtp/test_utf8.cmy b/cmd/mda-lmtp/test_utf8.cmy new file mode 100644 index 0000000..49dd924 --- /dev/null +++ b/cmd/mda-lmtp/test_utf8.cmy @@ -0,0 +1,33 @@ + +nc unix_listen .test-sock + +mda |= ./mda-lmtp --addr=.test-sock --addr_network=unix \ + -f fröm -d þo < test-email + +nc -> 220 Hola desde expect + +nc <~ LHLO .* +nc -> 250-Bienvenido! +nc -> 250 Contame... + +nc <- MAIL FROM: +nc -> 250 Aja + +nc <- RCPT TO:<þo> +nc -> 250 Aja + +nc <- DATA +nc -> 354 Dale + +nc <- Subject: test +nc <- +nc <- This is a test. +nc <- . + +nc -> 250 Recibido + +nc <- QUIT +nc -> 221 Chauchas + +mda wait 0 +