diff --git a/conn.go b/conn.go index ec9f686..2c3605e 100644 --- a/conn.go +++ b/conn.go @@ -276,6 +276,9 @@ func (c *Conn) handleGreet(enhanced bool, arg string) { if c.server.EnableDSN { caps = append(caps, "DSN") } + if c.server.EnableXOORG { + caps = append(caps, "XOORG") + } if c.server.MaxMessageBytes > 0 { caps = append(caps, fmt.Sprintf("SIZE %v", c.server.MaxMessageBytes)) } else { @@ -339,6 +342,12 @@ func (c *Conn) handleMail(arg string) { } opts.Size = int64(size) + case "XOORG": + if !c.server.EnableXOORG { + c.writeResponse(504, EnhancedCode{5, 5, 4}, "EnableXOORG is not implemented") + return + } + opts.XOORG = value case "SMTPUTF8": if !c.server.EnableSMTPUTF8 { c.writeResponse(504, EnhancedCode{5, 5, 4}, "SMTPUTF8 is not implemented") diff --git a/server.go b/server.go index 7c23a31..d1ebbae 100644 --- a/server.go +++ b/server.go @@ -57,6 +57,10 @@ type Server struct { // Should be used only if backend supports it. EnableDSN bool + // Advertise XOORG capability. + // Should be used only if backend supports it. + EnableXOORG bool + // The server backend. Backend Backend diff --git a/server_test.go b/server_test.go index 206d336..31600bc 100644 --- a/server_test.go +++ b/server_test.go @@ -1514,3 +1514,47 @@ func TestServerDSNwithSMTPUTF8(t *testing.T) { t.Fatal("Invalid ORCPT address:", val) } } + +func TestServerXOORG(t *testing.T) { + be, s, c, scanner, caps := testServerEhlo(t, + func(s *smtp.Server) { + s.EnableXOORG = true + }) + defer s.Close() + defer c.Close() + + for _, cap := range []string{"XOORG"} { + if _, ok := caps[cap]; !ok { + t.Fatal("Missing capability:", cap) + } + } + + io.WriteString(c, "MAIL FROM: XOORG=test.com\r\n") + scanner.Scan() + if !strings.HasPrefix(scanner.Text(), "250 ") { + t.Fatal("Invalid MAIL response:", scanner.Text()) + } + + io.WriteString(c, "RCPT TO:\r\n") + scanner.Scan() + if !strings.HasPrefix(scanner.Text(), "250 ") { + t.Fatal("Invalid RCPT response:", scanner.Text()) + } + + // go on as usual + io.WriteString(c, "DATA\r\n") + scanner.Scan() + io.WriteString(c, "Hey <3\r\n") + io.WriteString(c, ".\r\n") + scanner.Scan() + if !strings.HasPrefix(scanner.Text(), "250 ") { + t.Fatal("Invalid DATA response:", scanner.Text()) + } + if len(be.messages) != 0 || len(be.anonmsgs) != 1 { + t.Fatal("Invalid number of sent messages:", be.messages, be.anonmsgs) + } + + if val := be.anonmsgs[0].Opts.XOORG; val != "test.com" { + t.Fatal("Invalid XOORG parameter value:", val) + } +} diff --git a/smtp.go b/smtp.go index 9563b11..ab0c105 100644 --- a/smtp.go +++ b/smtp.go @@ -56,6 +56,9 @@ type MailOptions struct { // Envelope identifier set by the client. EnvelopeID string + // Accepted Domain from Exchange Online, e.g. from OutgoingConnector + XOORG string + // The authorization identity asserted by the message sender in decoded // form with angle brackets stripped. //