From 9020489912edc769f515eed67c4648e1a5af684e Mon Sep 17 00:00:00 2001 From: Christian Joergensen Date: Mon, 21 Jul 2014 12:43:42 +0200 Subject: [PATCH] Added new Server field Hostname for the FQDN over the server (and updated various uses of the hostname). Moved Server.Addr to a parameter for ListenAndServe, as it was only used there. --- envelope.go | 4 ++-- example_test.go | 6 ++---- protocol.go | 2 ++ smtpd.go | 41 ++++++++++++++++++----------------------- smtpd_test.go | 7 ++++--- 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/envelope.go b/envelope.go index 29dd009..0e0f1bc 100644 --- a/envelope.go +++ b/envelope.go @@ -15,7 +15,7 @@ type Envelope struct { } // AddReceivedLine prepends a Received header to the Data -func (env *Envelope) AddReceivedLine(peer Peer, serverName string) { +func (env *Envelope) AddReceivedLine(peer Peer) { tlsDetails := "" @@ -38,7 +38,7 @@ func (env *Envelope) AddReceivedLine(peer Peer, serverName string) { "Received: from %s [%s] by %s with %s;%s\r\n\t%s\r\n", peer.HeloName, strings.Split(peer.Addr.String(), ":")[0], - serverName, + peer.ServerName, peer.Protocol, tlsDetails, time.Now().Format("Mon Jan 2 15:04:05 -0700 2006"), diff --git a/example_test.go b/example_test.go index 611a79b..bdfe3f5 100644 --- a/example_test.go +++ b/example_test.go @@ -12,13 +12,11 @@ func ExampleServer() { // No-op server. Accepts and discards server = &smtpd.Server{} - server.ListenAndServe() + server.ListenAndServe("127.0.0.1:10025") // Relay server. Accepts only from single IP address and forwards using the Gmail smtp server = &smtpd.Server{ - Addr: "0.0.0.0:10025", - HeloChecker: func(peer smtpd.Peer, name string) error { if !strings.HasPrefix(peer.Addr.String(), "42.42.42.42:") { return errors.New("Denied") @@ -44,5 +42,5 @@ func ExampleServer() { }, } - server.ListenAndServe() + server.ListenAndServe("127.0.0.1:10025") } diff --git a/protocol.go b/protocol.go index 5382040..7a7c09f 100644 --- a/protocol.go +++ b/protocol.go @@ -147,6 +147,8 @@ func (session *session) handleEHLO(cmd command) { session.peer.HeloName = cmd.fields[1] session.peer.Protocol = ESMTP + fmt.Fprintf(session.writer, "250-%s\r\n", session.server.Hostname) + extensions := session.extensions() if len(extensions) > 1 { diff --git a/smtpd.go b/smtpd.go index 460c416..08f84e0 100644 --- a/smtpd.go +++ b/smtpd.go @@ -7,13 +7,12 @@ import ( "fmt" "log" "net" - "os" "time" ) // Server defines the parameters for running the SMTP server type Server struct { - Addr string // Address to listen on when using ListenAndServe. (default: "127.0.0.1:10025") + Hostname string // Server hostname. (default: "localhost.localdomain") WelcomeMessage string // Initial server banner. (default: " ESMTP ready.") ReadTimeout time.Duration // Socket timeout for read operations. (default: 60s) @@ -58,12 +57,13 @@ const ( // Peer represents the client connecting to the server type Peer struct { - HeloName string // Server name used in HELO/EHLO command - Username string // Username from authentication, if authenticated - Password string // Password from authentication, if authenticated - Protocol Protocol // Protocol used, SMTP or ESMTP - Addr net.Addr // Network address - TLS *tls.ConnectionState // TLS Connection details, if on TLS + HeloName string // Server name used in HELO/EHLO command + Username string // Username from authentication, if authenticated + Password string // Password from authentication, if authenticated + Protocol Protocol // Protocol used, SMTP or ESMTP + ServerName string // A copy of Server.Hostname + Addr net.Addr // Network address + TLS *tls.ConnectionState // TLS Connection details, if on TLS } // Error represents an Error reported in the SMTP session. @@ -97,7 +97,10 @@ func (srv *Server) newSession(c net.Conn) (s *session) { conn: c, reader: bufio.NewReader(c), writer: bufio.NewWriter(c), - peer: Peer{Addr: c.RemoteAddr()}, + peer: Peer{ + Addr: c.RemoteAddr(), + ServerName: srv.Hostname, + }, } s.scanner = bufio.NewScanner(s.reader) @@ -106,12 +109,12 @@ func (srv *Server) newSession(c net.Conn) (s *session) { } -// ListenAndServe starts the SMTP server and listens on the address provided in Server.Addr -func (srv *Server) ListenAndServe() error { +// ListenAndServe starts the SMTP server and listens on the address provided +func (srv *Server) ListenAndServe(addr string) error { srv.configureDefaults() - l, err := net.Listen("tcp", srv.Addr) + l, err := net.Listen("tcp", addr) if err != nil { return err } @@ -195,20 +198,12 @@ func (srv *Server) configureDefaults() { log.Fatal("Cannot use ForceTLS with no TLSConfig") } - if srv.Addr == "" { - srv.Addr = "127.0.0.1:10025" + if srv.Hostname == "" { + srv.Hostname = "localhost.localdomain" } if srv.WelcomeMessage == "" { - - hostname, err := os.Hostname() - - if err != nil { - log.Fatal("Couldn't determine hostname: %s", err) - } - - srv.WelcomeMessage = fmt.Sprintf("%s ESMTP ready.", hostname) - + srv.WelcomeMessage = fmt.Sprintf("%s ESMTP ready.", srv.Hostname) } } diff --git a/smtpd_test.go b/smtpd_test.go index 2d817fd..c3d8b9a 100644 --- a/smtpd_test.go +++ b/smtpd_test.go @@ -123,10 +123,10 @@ func TestListenAndServe(t *testing.T) { ln.Close() - server := &smtpd.Server{Addr: addr} + server := &smtpd.Server{} go func() { - server.ListenAndServe() + server.ListenAndServe(addr) }() time.Sleep(100 * time.Millisecond) @@ -1158,8 +1158,9 @@ func TestEnvelopeReceived(t *testing.T) { defer ln.Close() server := &smtpd.Server{ + Hostname: "foobar.example.net", Handler: func(peer smtpd.Peer, env smtpd.Envelope) error { - env.AddReceivedLine(peer, "foobar.example.net") + env.AddReceivedLine(peer) if !bytes.HasPrefix(env.Data, []byte("Received: from localhost [127.0.0.1] by foobar.example.net with ESMTP;")) { t.Fatal("Wrong received line.") }