Skip to content

Commit

Permalink
Merge pull request #322 from atc0005/i321-skip-login-imap-cmd-attempt…
Browse files Browse the repository at this point in the history
…-if-logindisabled-advertised

Skip `LOGIN` attempt if `LOGINDISABLED` is set
  • Loading branch information
atc0005 authored Nov 18, 2022
2 parents 19f44e2 + bccf3b4 commit bc0d7d1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
36 changes: 32 additions & 4 deletions internal/mbxs/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,11 @@ func Connect(server string, port int, netType string, minTLSVer uint16, logger z
}

// Login uses the provided client connection and credentials to login to the
// remote server.
func Login(client *client.Client, username string, password string, logger zerolog.Logger) error {
// IMAP server using plaintext authentication. Most servers will reject logins
// unless TLS is used.
func Login(c *client.Client, username string, password string, logger zerolog.Logger) error {

if client == nil {
if c == nil {
errMsg := fmt.Sprintf(
"invalid (nil) client received while attempting login for account %s",
username,
Expand All @@ -264,8 +265,35 @@ func Login(client *client.Client, username string, password string, logger zerol
return fmt.Errorf(errMsg)
}

// Due to logic applied during connection establishment this is highly
// unlikely to be true, but on the mischance that it is we issue a
// warning.
if !c.IsTLS() {
logger.Warn().Msg("WARNING: Connection to server is insecure (TLS is not enabled)")
}

// Make sure that LOGINDISABLED capability has not been set. When this is
// advertised by the server the LOGIN command is rejected. A common
// scenario where this capability is set is when the client has not yet
// established a secure TLS connection.
// https://datatracker.ietf.org/doc/html/rfc3501#section-6.2.3
loginDisabled, capErr := c.Support(IMAPv4CapabilityLoginDisabled)
if capErr != nil {
return fmt.Errorf(
"failed to detect support for logins: %w",
capErr,
)
}

if loginDisabled {
return fmt.Errorf(
"server has disabled logins: %w",
client.ErrLoginDisabled,
)
}

logger.Debug().Msg("Logging in")
if err := client.Login(username, password); err != nil {
if err := c.Login(username, password); err != nil {
errMsg := "login error occurred"
logger.Error().Err(err).Msg(errMsg)

Expand Down
19 changes: 19 additions & 0 deletions internal/mbxs/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,22 @@ const (
// NetTypeTCP6 indicates an IPv6-only network.
NetTypeTCP6 string = "tcp6"
)

// IMAP commands
const (

// The LOGIN command identifies the client to the server and carries the
// plaintext password authenticating this user.
// https://datatracker.ietf.org/doc/html/rfc3501#section-6.2.3
IMAPv4CommandLogin string = "LOGIN"
)

// IMAP capabilities
const (

// The LOGINDISABLED capability indicates that the LOGIN command is not
// permitted. This is most often due to TLS not active for the current
// connection.
// https://datatracker.ietf.org/doc/html/rfc3501#section-6.1.1
IMAPv4CapabilityLoginDisabled string = "LOGINDISABLED"
)

0 comments on commit bc0d7d1

Please sign in to comment.