mirror of
https://github.com/jhillyerd/inbucket.git
synced 2026-10-29 13:42:30 +00:00
fix(pop3): track STLS state per session instead of per server (#626)
The TLS connection state lived on the shared POP3 Server, and Session reached it through its embedded *Server. Once any client completed STLS, every later session saw a non-nil state: CAPA stopped advertising STLS and the STLS command returned "-ERR A TLS session already agreed upon." until the server restarted. Sessions also wrote the shared field concurrently without synchronization. Move tlsState to Session. ForceTLS sessions set it when the session starts, and STLS sets it on the negotiating session only. TestSTLSPerSession runs CAPA, STLS and a TLS handshake on two sessions of one server; it fails against the previous code on the second session. Signed-off-by: Antoine Deschênes <antoine@antoinedeschenes.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
94472ab496
commit
9876bb2bd9
+19
-16
@@ -60,19 +60,20 @@ var commands = map[string]bool{
|
||||
|
||||
// Session defines an active POP3 session
|
||||
type Session struct {
|
||||
*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.
|
||||
*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.
|
||||
tlsState *tls.ConnectionState // TLS connection state, nil until TLS is set up.
|
||||
}
|
||||
|
||||
// NewSession creates a new POP3 session
|
||||
@@ -107,11 +108,12 @@ func (s *Server) startSession(ctx context.Context, id int, conn net.Conn) {
|
||||
Int("session", id).Logger()
|
||||
logger.Debug().Msgf("ForceTLS: %t", s.config.ForceTLS)
|
||||
connToClose := conn
|
||||
var tlsState *tls.ConnectionState
|
||||
if s.config.ForceTLS {
|
||||
logger.Debug().Msg("Setting up TLS for ForceTLS")
|
||||
tlsConn := tls.Server(conn, s.tlsConfig)
|
||||
s.tlsState = new(tls.ConnectionState)
|
||||
*s.tlsState = tlsConn.ConnectionState()
|
||||
tlsState = new(tls.ConnectionState)
|
||||
*tlsState = tlsConn.ConnectionState()
|
||||
conn = tlsConn
|
||||
}
|
||||
|
||||
@@ -127,6 +129,7 @@ func (s *Server) startSession(ctx context.Context, id int, conn net.Conn) {
|
||||
}()
|
||||
|
||||
ssn := NewSession(s, id, conn, logger)
|
||||
ssn.tlsState = tlsState
|
||||
ssn.send(fmt.Sprintf("+OK Inbucket POP3 server ready <%v.%v@%v>", os.Getpid(),
|
||||
time.Now().Unix(), s.config.Domain))
|
||||
|
||||
@@ -144,7 +147,7 @@ func (s *Server) startSession(ctx context.Context, id int, conn net.Conn) {
|
||||
ssn.send("USER")
|
||||
ssn.send("UIDL")
|
||||
ssn.send("IMPLEMENTATION Inbucket")
|
||||
if s.tlsConfig != nil && s.tlsState == nil && !s.config.ForceTLS {
|
||||
if s.tlsConfig != nil && ssn.tlsState == nil && !s.config.ForceTLS {
|
||||
ssn.send("STLS")
|
||||
}
|
||||
ssn.send(".")
|
||||
|
||||
Reference in New Issue
Block a user