diff --git a/src/notifications/go.mod b/src/notifications/go.mod index 9717ef8b..79da65e0 100644 --- a/src/notifications/go.mod +++ b/src/notifications/go.mod @@ -5,7 +5,7 @@ go 1.26.4 require ( github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/PuerkitoBio/goquery v1.12.0 - github.com/chrj/smtpd v1.0.0 + github.com/chrj/smtpd v1.0.1 github.com/cloudfoundry-community/go-uaa v0.3.6 github.com/go-sql-driver/mysql v1.10.0 github.com/golang-jwt/jwt/v5 v5.3.1 diff --git a/src/notifications/go.sum b/src/notifications/go.sum index d3641b07..918746d5 100644 --- a/src/notifications/go.sum +++ b/src/notifications/go.sum @@ -10,8 +10,8 @@ github.com/PuerkitoBio/goquery v1.12.0 h1:pAcL4g3WRXekcB9AU/y1mbKez2dbY2AajVhtkO github.com/PuerkitoBio/goquery v1.12.0/go.mod h1:802ej+gV2y7bbIhOIoPY5sT183ZW0YFofScC4q/hIpQ= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= -github.com/chrj/smtpd v1.0.0 h1:jChSfLzAhrSxTky0EZ6oW+UKiqdnepdknWYRkPeA+ZE= -github.com/chrj/smtpd v1.0.0/go.mod h1:zEP61gNDlWp/jdUqBcq/ykIbgOERyRvwfMsRLl3h9gM= +github.com/chrj/smtpd v1.0.1 h1:HmC5/iGdI27q4JJn58uaANAOUE+QC7ZYZnDlQWJEph4= +github.com/chrj/smtpd v1.0.1/go.mod h1:zEP61gNDlWp/jdUqBcq/ykIbgOERyRvwfMsRLl3h9gM= github.com/cloudfoundry-community/go-uaa v0.3.6 h1:G4yWO3Axi5eTOvqfWBBSWiA1Mkonlk/q2DxGXIYtbGE= github.com/cloudfoundry-community/go-uaa v0.3.6/go.mod h1:EbMPp8sKxKmz0+WKa6qPfdshI8NZYoD4FJAAIbQ9Vl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/src/notifications/vendor/github.com/chrj/smtpd/README.md b/src/notifications/vendor/github.com/chrj/smtpd/README.md index e107c3f6..331dcd61 100644 --- a/src/notifications/vendor/github.com/chrj/smtpd/README.md +++ b/src/notifications/vendor/github.com/chrj/smtpd/README.md @@ -8,7 +8,7 @@ Features * STARTTLS (using `crypto/tls`) * Authentication (PLAIN/LOGIN, only after STARTTLS) -* [XCLIENT](http://www.postfix.org/XCLIENT_README.html) and [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) (for running behind a proxy) +* [XCLIENT](http://www.postfix.org/XCLIENT_README.html) and [PROXY protocol](https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) (for running behind a proxy). The `PROXY` command comes first in a session, and a later one gets a `503` reply. * Connection, HELO, sender and recipient checks for rejecting e-mails using callbacks * Configurable limits for: connection count, message size and recipient count * Hands incoming e-mail off to a configured callback function diff --git a/src/notifications/vendor/github.com/chrj/smtpd/protocol.go b/src/notifications/vendor/github.com/chrj/smtpd/protocol.go index 97ac3da2..1b89a35b 100644 --- a/src/notifications/vendor/github.com/chrj/smtpd/protocol.go +++ b/src/notifications/vendor/github.com/chrj/smtpd/protocol.go @@ -61,6 +61,10 @@ func parseLine(line string) (cmd command) { func (session *session) handle(line string) { + // The PROXY header of a proxy stands first in the session, so every + // command closes the window for it. See handlePROXY. + defer func() { session.ranCommand = true }() + cmd := parseLine(line) // Commands are dispatched to the appropriate handler functions. @@ -617,6 +621,15 @@ func (session *session) handlePROXY(cmd command) { return } + // The proxy writes its header before it passes on anything of the client, + // so a header that comes after a command comes from the client. A client + // that writes its own address takes the identity of another one, and the + // ConnectionChecker and the checkers after it all read Peer.Addr. + if session.ranCommand { + session.reply(503, "PROXY comes first in a session, before every other command") + return + } + if len(cmd.fields) < 6 { session.reply(502, "Couldn't decode the command.") return diff --git a/src/notifications/vendor/github.com/chrj/smtpd/smtpd.go b/src/notifications/vendor/github.com/chrj/smtpd/smtpd.go index 347e3602..300f25dc 100644 --- a/src/notifications/vendor/github.com/chrj/smtpd/smtpd.go +++ b/src/notifications/vendor/github.com/chrj/smtpd/smtpd.go @@ -112,6 +112,13 @@ type session struct { scanner *bufio.Scanner tls bool + + // ranCommand says that the session ran a command already. The PROXY + // header of a proxy stands before everything else: the proxy writes it, + // and only then does it pass on what the client sends. A PROXY command + // that comes later therefore comes from the client behind the proxy, and + // it would write the address that every checker after it reads. + ranCommand bool } func (srv *Server) newSession(c net.Conn) (s *session) { diff --git a/src/notifications/vendor/modules.txt b/src/notifications/vendor/modules.txt index ddc28461..06fe95d6 100644 --- a/src/notifications/vendor/modules.txt +++ b/src/notifications/vendor/modules.txt @@ -16,7 +16,7 @@ github.com/PuerkitoBio/goquery # github.com/andybalholm/cascadia v1.3.3 ## explicit; go 1.16 github.com/andybalholm/cascadia -# github.com/chrj/smtpd v1.0.0 +# github.com/chrj/smtpd v1.0.1 ## explicit; go 1.25 github.com/chrj/smtpd # github.com/cloudfoundry-community/go-uaa v0.3.6