Initial commit

main
Mari 3 years ago
commit c0eb4201ba
  1. 2
      .gitignore
  2. 5
      go.mod
  3. 4
      go.sum
  4. 107
      lda.go

2
.gitignore vendored

@ -0,0 +1,2 @@
.idea
lda

@ -0,0 +1,5 @@
module lmtpdelivery
go 1.15
require github.com/emersion/go-smtp v0.14.0

@ -0,0 +1,4 @@
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/emersion/go-smtp v0.14.0 h1:RYW203p+EcPjL8Z/ZpT9lZ6iOc8MG1MQzEx1UKEkXlA=
github.com/emersion/go-smtp v0.14.0/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=

107
lda.go

@ -0,0 +1,107 @@
package main
import (
"flag"
"fmt"
"github.com/emersion/go-smtp"
"io"
"net"
"os"
"regexp"
"strings"
)
func sendMail(from string, to string, socket string) (err error) {
conn, err := net.Dial("unix", socket)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed opening the socket <%s>: %s", socket, err)
return err
}
client, err := smtp.NewClientLMTP(conn, "localhost")
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed establishing the connection: %s", err)
return err
}
defer func() {
quitErr := client.Quit()
if quitErr != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed closing the connection: %s", quitErr)
}
}()
err = client.Mail(from, &smtp.MailOptions{})
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed establishing the envelope FROM <%s>: %s", from, err)
return err
}
err = client.Rcpt(to)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed establishing the envelope FROM <%s> TO <%s>: %s", from, to, err)
return err
}
var sendError *smtp.SMTPError
writer, err := client.LMTPData(func(rcpt string, status *smtp.SMTPError) {
if status != nil {
sendError = status
_, _ = fmt.Fprintf(os.Stderr, "Failed sending the message FROM <%s> TO <%s>: %s", from, rcpt, status)
}
})
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed opening the writing stream FROM <%s> TO <%s>: %s", from, to, err)
return err
}
_, err = io.Copy(writer, os.Stdin)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed copying the message FROM <%s> TO <%s> data: %s", from, to, err)
return err
}
err = writer.Close()
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Failed closing the writing stream FROM <%s> TO <%s>: %s", from, to, err)
return err
}
if sendError != nil {
return sendError
}
return nil
}
var UnwrapRe = regexp.MustCompile("^.*\\s*<([^<>]+)>\\s*$")
func unwrap(from string) string {
result := UnwrapRe.FindStringSubmatch(from)
if result == nil {
return from
}
return result[1]
}
func escapeAts(from string) string {
count := strings.Count(from, "@")
if count <= 1 {
return from
}
return strings.Replace(from, "@", ".at.", count - 1)
}
func main() {
from := flag.String("from", "", "The original envelope sender of the message.")
to := flag.String("to", "", "The envelope recipient of the message.")
socket := flag.String("socket", "/var/run/dovecot/lmtp", "The LMTP Unix socket to send on.")
escapeDoubledAts := flag.Bool("escapeDoubledAts", true, "True to escape multiple @ symbols.")
unwrapFrom := flag.Bool("unwrapBrackets", true, "True to unwrap unnecessary <> symbols.")
replaceUnknown := flag.Bool("replaceUnknown", true, "True to replace 'unknown' with a default value")
flag.Parse()
if *unwrapFrom {
*from = unwrap(*from)
}
if *escapeDoubledAts {
*from = escapeAts(*from)
}
if *replaceUnknown && *from == "unknown" {
*from = "unknown@unknown.invalid"
}
if err := sendMail(*from, *to, *socket); err != nil {
os.Exit(1)
}
}
Loading…
Cancel
Save