mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 09:37:02 +00:00
server: -netdebug flag now controls tracing for #90
Network trace is sent to stdout, no longer part of normal debug logging.
This commit is contained in:
@@ -59,6 +59,7 @@ func main() {
|
||||
pidfile := flag.String("pidfile", "", "Write our PID into the specified file.")
|
||||
logfile := flag.String("logfile", "stderr", "Write out log into the specified file.")
|
||||
logjson := flag.Bool("logjson", false, "Logs are written in JSON format.")
|
||||
netdebug := flag.Bool("netdebug", false, "Dump SMTP & POP3 network traffic to stdout.")
|
||||
flag.Usage = func() {
|
||||
fmt.Fprintln(os.Stderr, "Usage: inbucket [options]")
|
||||
flag.PrintDefaults()
|
||||
@@ -89,6 +90,10 @@ func main() {
|
||||
fmt.Fprintf(os.Stderr, "Configuration error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if *netdebug {
|
||||
conf.POP3.Debug = true
|
||||
conf.SMTP.Debug = true
|
||||
}
|
||||
// Setup signal handler.
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
@@ -45,6 +45,7 @@ type SMTP struct {
|
||||
MaxMessageBytes int `required:"true" default:"10240000" desc:"Maximum message size"`
|
||||
StoreMessages bool `required:"true" default:"true" desc:"Store incoming mail?"`
|
||||
Timeout time.Duration `required:"true" default:"300s" desc:"Idle network timeout"`
|
||||
Debug bool `ignored:"true"`
|
||||
}
|
||||
|
||||
// POP3 contains the POP3 server configuration.
|
||||
@@ -52,6 +53,7 @@ type POP3 struct {
|
||||
Addr string `required:"true" default:"0.0.0.0:1100" desc:"POP3 server IP4 host:port"`
|
||||
Domain string `required:"true" default:"inbucket" desc:"HELLO domain"`
|
||||
Timeout time.Duration `required:"true" default:"600s" desc:"Idle network timeout"`
|
||||
Debug bool `ignored:"true"`
|
||||
}
|
||||
|
||||
// Web contains the HTTP server configuration.
|
||||
|
||||
@@ -2,7 +2,6 @@ package pop3
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -58,26 +57,35 @@ var commands = map[string]bool{
|
||||
|
||||
// Session defines an active POP3 session
|
||||
type Session struct {
|
||||
server *Server // Reference to the server we belong to
|
||||
id int // Session ID number
|
||||
conn net.Conn // Our network connection
|
||||
remoteHost string // IP address of client
|
||||
sendError error // Used to bail out of read loop on send error
|
||||
state State // Current session state
|
||||
reader *bufio.Reader // Buffered reader for our net conn
|
||||
user string // Mailbox name
|
||||
messages []storage.Message // Slice of messages in mailbox
|
||||
retain []bool // Messages to retain upon UPDATE (true=retain)
|
||||
msgCount int // Number of undeleted messages
|
||||
logger zerolog.Logger
|
||||
server *Server // Reference to the server we belong to.
|
||||
id int // Session ID number.
|
||||
conn net.Conn // Our network connection.
|
||||
remoteHost string // IP address of client.
|
||||
sendError error // Used to bail out of read loop on send error.
|
||||
state State // Current session state.
|
||||
reader *bufio.Reader // Buffered reader for our net conn.
|
||||
user string // Mailbox name.
|
||||
messages []storage.Message // Slice of messages in mailbox.
|
||||
retain []bool // Messages to retain upon UPDATE (true=retain).
|
||||
msgCount int // Number of undeleted messages.
|
||||
logger zerolog.Logger // Session specific logger.
|
||||
debug bool // Print network traffic to stdout.
|
||||
}
|
||||
|
||||
// NewSession creates a new POP3 session
|
||||
func NewSession(server *Server, id int, conn net.Conn, logger zerolog.Logger) *Session {
|
||||
reader := bufio.NewReader(conn)
|
||||
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
||||
return &Session{server: server, id: id, conn: conn, state: AUTHORIZATION,
|
||||
reader: reader, remoteHost: host, logger: logger}
|
||||
return &Session{
|
||||
server: server,
|
||||
id: id,
|
||||
conn: conn,
|
||||
state: AUTHORIZATION,
|
||||
reader: reader,
|
||||
remoteHost: host,
|
||||
logger: logger,
|
||||
debug: server.config.Debug,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) String() string {
|
||||
@@ -550,41 +558,12 @@ func (s *Session) send(msg string) {
|
||||
}
|
||||
if _, err := fmt.Fprint(s.conn, msg+"\r\n"); err != nil {
|
||||
s.sendError = err
|
||||
s.logger.Warn().Msgf("Failed to send: '%v'", msg)
|
||||
s.logger.Warn().Msgf("Failed to send: %q", msg)
|
||||
return
|
||||
}
|
||||
s.logger.Debug().Msgf(">> %v >>", msg)
|
||||
}
|
||||
|
||||
// readByteLine reads a line of input into the provided buffer. Does
|
||||
// not reset the Buffer - please do so prior to calling.
|
||||
func (s *Session) readByteLine(buf *bytes.Buffer) error {
|
||||
if err := s.conn.SetReadDeadline(s.nextDeadline()); err != nil {
|
||||
return err
|
||||
if s.debug {
|
||||
fmt.Printf("%04d > %v\n", s.id, msg)
|
||||
}
|
||||
for {
|
||||
line, err := s.reader.ReadBytes('\r')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = buf.Write(line); err != nil {
|
||||
return err
|
||||
}
|
||||
// Read the next byte looking for '\n'
|
||||
c, err := s.reader.ReadByte()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := buf.WriteByte(c); err != nil {
|
||||
return err
|
||||
}
|
||||
if c == '\n' {
|
||||
// We've reached the end of the line, return
|
||||
return nil
|
||||
}
|
||||
// Else, keep looking
|
||||
}
|
||||
// Should be unreachable
|
||||
}
|
||||
|
||||
// Reads a line of input
|
||||
@@ -596,7 +575,9 @@ func (s *Session) readLine() (line string, err error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.logger.Debug().Msgf("<< %v <<", strings.TrimRight(line, "\r\n"))
|
||||
if s.debug {
|
||||
fmt.Printf("%04d %v\n", s.id, strings.TrimRight(line, "\r\n"))
|
||||
}
|
||||
return line, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ import (
|
||||
|
||||
// Server defines an instance of our POP3 server
|
||||
type Server struct {
|
||||
// TODO(#91) Refactor config items out of this struct
|
||||
config config.POP3
|
||||
host string
|
||||
domain string
|
||||
timeout time.Duration
|
||||
@@ -25,6 +27,7 @@ type Server struct {
|
||||
// New creates a new Server struct
|
||||
func New(cfg config.POP3, shutdownChan chan bool, store storage.Store) *Server {
|
||||
return &Server{
|
||||
config: cfg,
|
||||
host: cfg.Addr,
|
||||
domain: cfg.Domain,
|
||||
store: store,
|
||||
|
||||
@@ -80,7 +80,8 @@ type Session struct {
|
||||
reader *bufio.Reader
|
||||
from string
|
||||
recipients []*policy.Recipient
|
||||
logger zerolog.Logger
|
||||
logger zerolog.Logger // Session specific logger.
|
||||
debug bool // Print network traffic to stdout.
|
||||
}
|
||||
|
||||
// NewSession creates a new Session for the given connection
|
||||
@@ -96,6 +97,7 @@ func NewSession(server *Server, id int, conn net.Conn, logger zerolog.Logger) *S
|
||||
remoteHost: host,
|
||||
recipients: make([]*policy.Recipient, 0),
|
||||
logger: logger,
|
||||
debug: server.config.Debug,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +435,9 @@ func (s *Session) send(msg string) {
|
||||
s.logger.Warn().Msgf("Failed to send: %q", msg)
|
||||
return
|
||||
}
|
||||
s.logger.Debug().Msgf(">> %v >>", msg)
|
||||
if s.debug {
|
||||
fmt.Printf("%04d > %v\n", s.id, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// readByteLine reads a line of input, returns byte slice.
|
||||
@@ -441,7 +445,11 @@ func (s *Session) readByteLine() ([]byte, error) {
|
||||
if err := s.conn.SetReadDeadline(s.nextDeadline()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.reader.ReadBytes('\n')
|
||||
b, err := s.reader.ReadBytes('\n')
|
||||
if err == nil && s.debug {
|
||||
fmt.Printf("%04d %s\n", s.id, bytes.TrimRight(b, "\r\n"))
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
|
||||
// Reads a line of input
|
||||
@@ -453,7 +461,9 @@ func (s *Session) readLine() (line string, err error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
s.logger.Debug().Msgf("<< %v <<", strings.TrimRight(line, "\r\n"))
|
||||
if s.debug {
|
||||
fmt.Printf("%04d %v\n", s.id, strings.TrimRight(line, "\r\n"))
|
||||
}
|
||||
return line, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ func init() {
|
||||
|
||||
// Server holds the configuration and state of our SMTP server
|
||||
type Server struct {
|
||||
// TODO(#91) Refactor config items out of this struct
|
||||
config config.SMTP
|
||||
// Configuration
|
||||
host string
|
||||
domain string
|
||||
@@ -86,6 +88,7 @@ func NewServer(
|
||||
apolicy *policy.Addressing,
|
||||
) *Server {
|
||||
return &Server{
|
||||
config: cfg,
|
||||
host: cfg.Addr,
|
||||
domain: cfg.Domain,
|
||||
domainNoStore: strings.ToLower(cfg.DomainNoStore),
|
||||
|
||||
Reference in New Issue
Block a user