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.

This commit is contained in:
Christian Joergensen 2014-07-21 12:43:42 +02:00
parent 4ba7fea939
commit 9020489912
5 changed files with 28 additions and 32 deletions

View file

@ -15,7 +15,7 @@ type Envelope struct {
} }
// AddReceivedLine prepends a Received header to the Data // AddReceivedLine prepends a Received header to the Data
func (env *Envelope) AddReceivedLine(peer Peer, serverName string) { func (env *Envelope) AddReceivedLine(peer Peer) {
tlsDetails := "" 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", "Received: from %s [%s] by %s with %s;%s\r\n\t%s\r\n",
peer.HeloName, peer.HeloName,
strings.Split(peer.Addr.String(), ":")[0], strings.Split(peer.Addr.String(), ":")[0],
serverName, peer.ServerName,
peer.Protocol, peer.Protocol,
tlsDetails, tlsDetails,
time.Now().Format("Mon Jan 2 15:04:05 -0700 2006"), time.Now().Format("Mon Jan 2 15:04:05 -0700 2006"),

View file

@ -12,13 +12,11 @@ func ExampleServer() {
// No-op server. Accepts and discards // No-op server. Accepts and discards
server = &smtpd.Server{} 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 // Relay server. Accepts only from single IP address and forwards using the Gmail smtp
server = &smtpd.Server{ server = &smtpd.Server{
Addr: "0.0.0.0:10025",
HeloChecker: func(peer smtpd.Peer, name string) error { HeloChecker: func(peer smtpd.Peer, name string) error {
if !strings.HasPrefix(peer.Addr.String(), "42.42.42.42:") { if !strings.HasPrefix(peer.Addr.String(), "42.42.42.42:") {
return errors.New("Denied") return errors.New("Denied")
@ -44,5 +42,5 @@ func ExampleServer() {
}, },
} }
server.ListenAndServe() server.ListenAndServe("127.0.0.1:10025")
} }

View file

@ -147,6 +147,8 @@ func (session *session) handleEHLO(cmd command) {
session.peer.HeloName = cmd.fields[1] session.peer.HeloName = cmd.fields[1]
session.peer.Protocol = ESMTP session.peer.Protocol = ESMTP
fmt.Fprintf(session.writer, "250-%s\r\n", session.server.Hostname)
extensions := session.extensions() extensions := session.extensions()
if len(extensions) > 1 { if len(extensions) > 1 {

View file

@ -7,13 +7,12 @@ import (
"fmt" "fmt"
"log" "log"
"net" "net"
"os"
"time" "time"
) )
// Server defines the parameters for running the SMTP server // Server defines the parameters for running the SMTP server
type Server struct { 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: "<hostname> ESMTP ready.") WelcomeMessage string // Initial server banner. (default: "<hostname> ESMTP ready.")
ReadTimeout time.Duration // Socket timeout for read operations. (default: 60s) ReadTimeout time.Duration // Socket timeout for read operations. (default: 60s)
@ -58,12 +57,13 @@ const (
// Peer represents the client connecting to the server // Peer represents the client connecting to the server
type Peer struct { type Peer struct {
HeloName string // Server name used in HELO/EHLO command HeloName string // Server name used in HELO/EHLO command
Username string // Username from authentication, if authenticated Username string // Username from authentication, if authenticated
Password string // Password from authentication, if authenticated Password string // Password from authentication, if authenticated
Protocol Protocol // Protocol used, SMTP or ESMTP Protocol Protocol // Protocol used, SMTP or ESMTP
Addr net.Addr // Network address ServerName string // A copy of Server.Hostname
TLS *tls.ConnectionState // TLS Connection details, if on TLS Addr net.Addr // Network address
TLS *tls.ConnectionState // TLS Connection details, if on TLS
} }
// Error represents an Error reported in the SMTP session. // Error represents an Error reported in the SMTP session.
@ -97,7 +97,10 @@ func (srv *Server) newSession(c net.Conn) (s *session) {
conn: c, conn: c,
reader: bufio.NewReader(c), reader: bufio.NewReader(c),
writer: bufio.NewWriter(c), writer: bufio.NewWriter(c),
peer: Peer{Addr: c.RemoteAddr()}, peer: Peer{
Addr: c.RemoteAddr(),
ServerName: srv.Hostname,
},
} }
s.scanner = bufio.NewScanner(s.reader) 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 // ListenAndServe starts the SMTP server and listens on the address provided
func (srv *Server) ListenAndServe() error { func (srv *Server) ListenAndServe(addr string) error {
srv.configureDefaults() srv.configureDefaults()
l, err := net.Listen("tcp", srv.Addr) l, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
return err return err
} }
@ -195,20 +198,12 @@ func (srv *Server) configureDefaults() {
log.Fatal("Cannot use ForceTLS with no TLSConfig") log.Fatal("Cannot use ForceTLS with no TLSConfig")
} }
if srv.Addr == "" { if srv.Hostname == "" {
srv.Addr = "127.0.0.1:10025" srv.Hostname = "localhost.localdomain"
} }
if srv.WelcomeMessage == "" { if srv.WelcomeMessage == "" {
srv.WelcomeMessage = fmt.Sprintf("%s ESMTP ready.", srv.Hostname)
hostname, err := os.Hostname()
if err != nil {
log.Fatal("Couldn't determine hostname: %s", err)
}
srv.WelcomeMessage = fmt.Sprintf("%s ESMTP ready.", hostname)
} }
} }

View file

@ -123,10 +123,10 @@ func TestListenAndServe(t *testing.T) {
ln.Close() ln.Close()
server := &smtpd.Server{Addr: addr} server := &smtpd.Server{}
go func() { go func() {
server.ListenAndServe() server.ListenAndServe(addr)
}() }()
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
@ -1158,8 +1158,9 @@ func TestEnvelopeReceived(t *testing.T) {
defer ln.Close() defer ln.Close()
server := &smtpd.Server{ server := &smtpd.Server{
Hostname: "foobar.example.net",
Handler: func(peer smtpd.Peer, env smtpd.Envelope) error { 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;")) { if !bytes.HasPrefix(env.Data, []byte("Received: from localhost [127.0.0.1] by foobar.example.net with ESMTP;")) {
t.Fatal("Wrong received line.") t.Fatal("Wrong received line.")
} }