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:
parent
d28767953f
commit
1d5d658be6
5 changed files with 28 additions and 32 deletions
|
@ -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"),
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
41
smtpd.go
41
smtpd.go
|
@ -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)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue