mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 09:37:02 +00:00
pop3, smtp: embed Server struct into Session for #91
This commit is contained in:
@@ -57,7 +57,7 @@ var commands = map[string]bool{
|
|||||||
|
|
||||||
// Session defines an active POP3 session
|
// Session defines an active POP3 session
|
||||||
type Session struct {
|
type Session struct {
|
||||||
server *Server // Reference to the server we belong to.
|
*Server // Reference to the server we belong to.
|
||||||
id int // Session ID number.
|
id int // Session ID number.
|
||||||
conn net.Conn // Our network connection.
|
conn net.Conn // Our network connection.
|
||||||
remoteHost string // IP address of client.
|
remoteHost string // IP address of client.
|
||||||
@@ -77,7 +77,7 @@ func NewSession(server *Server, id int, conn net.Conn, logger zerolog.Logger) *S
|
|||||||
reader := bufio.NewReader(conn)
|
reader := bufio.NewReader(conn)
|
||||||
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
||||||
return &Session{
|
return &Session{
|
||||||
server: server,
|
Server: server,
|
||||||
id: id,
|
id: id,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
state: AUTHORIZATION,
|
state: AUTHORIZATION,
|
||||||
@@ -507,7 +507,7 @@ func (s *Session) sendMessageTop(msg storage.Message, lineCount int) {
|
|||||||
// Load the users mailbox
|
// Load the users mailbox
|
||||||
func (s *Session) loadMailbox() {
|
func (s *Session) loadMailbox() {
|
||||||
s.logger = s.logger.With().Str("mailbox", s.user).Logger()
|
s.logger = s.logger.With().Str("mailbox", s.user).Logger()
|
||||||
m, err := s.server.store.GetMessages(s.user)
|
m, err := s.store.GetMessages(s.user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error().Msgf("Failed to load messages for %v: %v", s.user, err)
|
s.logger.Error().Msgf("Failed to load messages for %v: %v", s.user, err)
|
||||||
}
|
}
|
||||||
@@ -533,7 +533,7 @@ func (s *Session) processDeletes() {
|
|||||||
for i, msg := range s.messages {
|
for i, msg := range s.messages {
|
||||||
if !s.retain[i] {
|
if !s.retain[i] {
|
||||||
s.logger.Debug().Str("id", msg.ID()).Msg("Deleting message")
|
s.logger.Debug().Str("id", msg.ID()).Msg("Deleting message")
|
||||||
if err := s.server.store.RemoveMessage(s.user, msg.ID()); err != nil {
|
if err := s.store.RemoveMessage(s.user, msg.ID()); err != nil {
|
||||||
s.logger.Warn().Str("id", msg.ID()).Err(err).Msg("Error deleting message")
|
s.logger.Warn().Str("id", msg.ID()).Err(err).Msg("Error deleting message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -547,7 +547,7 @@ func (s *Session) enterState(state State) {
|
|||||||
|
|
||||||
// nextDeadline calculates the next read or write deadline based on configured timeout.
|
// nextDeadline calculates the next read or write deadline based on configured timeout.
|
||||||
func (s *Session) nextDeadline() time.Time {
|
func (s *Session) nextDeadline() time.Time {
|
||||||
return time.Now().Add(s.server.config.Timeout)
|
return time.Now().Add(s.config.Timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send requested message, store errors in Session.sendError
|
// Send requested message, store errors in Session.sendError
|
||||||
|
|||||||
@@ -70,18 +70,18 @@ var commands = map[string]bool{
|
|||||||
|
|
||||||
// Session holds the state of an SMTP session
|
// Session holds the state of an SMTP session
|
||||||
type Session struct {
|
type Session struct {
|
||||||
server *Server
|
*Server // Server this session belongs to.
|
||||||
id int
|
id int // Session ID.
|
||||||
conn net.Conn
|
conn net.Conn // TCP connection.
|
||||||
remoteDomain string
|
remoteDomain string // Remote domain from HELO command.
|
||||||
remoteHost string
|
remoteHost string // Remote host.
|
||||||
sendError error
|
sendError error // Last network send error.
|
||||||
state State
|
state State // Session state machine.
|
||||||
reader *bufio.Reader
|
reader *bufio.Reader // Buffered reading for TCP conn.
|
||||||
from string
|
from string // Sender from MAIL command.
|
||||||
recipients []*policy.Recipient
|
recipients []*policy.Recipient // Recipients from RCPT commands.
|
||||||
logger zerolog.Logger // Session specific logger.
|
logger zerolog.Logger // Session specific logger.
|
||||||
debug bool // Print network traffic to stdout.
|
debug bool // Print network traffic to stdout.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSession creates a new Session for the given connection
|
// NewSession creates a new Session for the given connection
|
||||||
@@ -89,7 +89,7 @@ func NewSession(server *Server, id int, conn net.Conn, logger zerolog.Logger) *S
|
|||||||
reader := bufio.NewReader(conn)
|
reader := bufio.NewReader(conn)
|
||||||
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
||||||
return &Session{
|
return &Session{
|
||||||
server: server,
|
Server: server,
|
||||||
id: id,
|
id: id,
|
||||||
conn: conn,
|
conn: conn,
|
||||||
state: GREET,
|
state: GREET,
|
||||||
@@ -244,7 +244,7 @@ func (s *Session) greetHandler(cmd string, arg string) {
|
|||||||
s.remoteDomain = domain
|
s.remoteDomain = domain
|
||||||
s.send("250-Great, let's get this show on the road")
|
s.send("250-Great, let's get this show on the road")
|
||||||
s.send("250-8BITMIME")
|
s.send("250-8BITMIME")
|
||||||
s.send(fmt.Sprintf("250 SIZE %v", s.server.config.MaxMessageBytes))
|
s.send(fmt.Sprintf("250 SIZE %v", s.config.MaxMessageBytes))
|
||||||
s.enterState(READY)
|
s.enterState(READY)
|
||||||
default:
|
default:
|
||||||
s.ooSeq(cmd)
|
s.ooSeq(cmd)
|
||||||
@@ -296,7 +296,7 @@ func (s *Session) readyHandler(cmd string, arg string) {
|
|||||||
s.logger.Warn().Msgf("Unable to parse SIZE %q as an integer", args["SIZE"])
|
s.logger.Warn().Msgf("Unable to parse SIZE %q as an integer", args["SIZE"])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if int(size) > s.server.config.MaxMessageBytes {
|
if int(size) > s.config.MaxMessageBytes {
|
||||||
s.send("552 Max message size exceeded")
|
s.send("552 Max message size exceeded")
|
||||||
s.logger.Warn().Msgf("Client wanted to send oversized message: %v", args["SIZE"])
|
s.logger.Warn().Msgf("Client wanted to send oversized message: %v", args["SIZE"])
|
||||||
return
|
return
|
||||||
@@ -323,17 +323,17 @@ func (s *Session) mailHandler(cmd string, arg string) {
|
|||||||
}
|
}
|
||||||
// This trim is probably too forgiving
|
// This trim is probably too forgiving
|
||||||
addr := strings.Trim(arg[3:], "<> ")
|
addr := strings.Trim(arg[3:], "<> ")
|
||||||
recip, err := s.server.addrPolicy.NewRecipient(addr)
|
recip, err := s.addrPolicy.NewRecipient(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.send("501 Bad recipient address syntax")
|
s.send("501 Bad recipient address syntax")
|
||||||
s.logger.Warn().Msgf("Bad address as RCPT arg: %q, %s", addr, err)
|
s.logger.Warn().Msgf("Bad address as RCPT arg: %q, %s", addr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(s.recipients) >= s.server.config.MaxRecipients {
|
if len(s.recipients) >= s.config.MaxRecipients {
|
||||||
s.logger.Warn().Msgf("Maximum limit of %v recipients reached",
|
s.logger.Warn().Msgf("Maximum limit of %v recipients reached",
|
||||||
s.server.config.MaxRecipients)
|
s.config.MaxRecipients)
|
||||||
s.send(fmt.Sprintf("552 Maximum limit of %v recipients reached",
|
s.send(fmt.Sprintf("552 Maximum limit of %v recipients reached",
|
||||||
s.server.config.MaxRecipients))
|
s.config.MaxRecipients))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.recipients = append(s.recipients, recip)
|
s.recipients = append(s.recipients, recip)
|
||||||
@@ -381,10 +381,10 @@ func (s *Session) dataHandler() {
|
|||||||
if recip.ShouldStore() {
|
if recip.ShouldStore() {
|
||||||
// Generate Received header.
|
// Generate Received header.
|
||||||
prefix := fmt.Sprintf("Received: from %s ([%s]) by %s\r\n for <%s>; %s\r\n",
|
prefix := fmt.Sprintf("Received: from %s ([%s]) by %s\r\n for <%s>; %s\r\n",
|
||||||
s.remoteDomain, s.remoteHost, s.server.config.Domain, recip.Address.Address,
|
s.remoteDomain, s.remoteHost, s.config.Domain, recip.Address.Address,
|
||||||
tstamp)
|
tstamp)
|
||||||
// Deliver message.
|
// Deliver message.
|
||||||
_, err := s.server.manager.Deliver(
|
_, err := s.manager.Deliver(
|
||||||
recip, s.from, s.recipients, prefix, msgBuf.Bytes())
|
recip, s.from, s.recipients, prefix, msgBuf.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error().Msgf("delivery for %v: %v", recip.LocalPart, err)
|
s.logger.Error().Msgf("delivery for %v: %v", recip.LocalPart, err)
|
||||||
@@ -405,7 +405,7 @@ func (s *Session) dataHandler() {
|
|||||||
lineBuf = lineBuf[1:]
|
lineBuf = lineBuf[1:]
|
||||||
}
|
}
|
||||||
msgBuf.Write(lineBuf)
|
msgBuf.Write(lineBuf)
|
||||||
if msgBuf.Len() > s.server.config.MaxMessageBytes {
|
if msgBuf.Len() > s.config.MaxMessageBytes {
|
||||||
s.send("552 Maximum message size exceeded")
|
s.send("552 Maximum message size exceeded")
|
||||||
s.logger.Warn().Msgf("Max message size exceeded while in DATA")
|
s.logger.Warn().Msgf("Max message size exceeded while in DATA")
|
||||||
s.reset()
|
s.reset()
|
||||||
@@ -420,12 +420,12 @@ func (s *Session) enterState(state State) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) greet() {
|
func (s *Session) greet() {
|
||||||
s.send(fmt.Sprintf("220 %v Inbucket SMTP ready", s.server.config.Domain))
|
s.send(fmt.Sprintf("220 %v Inbucket SMTP ready", s.config.Domain))
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextDeadline calculates the next read or write deadline based on configured timeout.
|
// nextDeadline calculates the next read or write deadline based on configured timeout.
|
||||||
func (s *Session) nextDeadline() time.Time {
|
func (s *Session) nextDeadline() time.Time {
|
||||||
return time.Now().Add(s.server.config.Timeout)
|
return time.Now().Add(s.config.Timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send requested message, store errors in Session.sendError
|
// Send requested message, store errors in Session.sendError
|
||||||
|
|||||||
Reference in New Issue
Block a user