Changeset 726 in code for trunk/downstream.go


Ignore:
Timestamp:
Nov 29, 2021, 12:14:16 PM (4 years ago)
Author:
contact
Message:

Return more descriptive auth failure errors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/downstream.go

    r725 r726  
    5555}
    5656
    57 var errAuthFailed = ircError{&irc.Message{
    58         Command: irc.ERR_PASSWDMISMATCH,
    59         Params:  []string{"*", "Invalid username or password"},
    60 }}
     57// authError is an authentication error.
     58type authError struct {
     59        // Internal error cause. This will not be revealed to the user.
     60        err error
     61        // Error cause which can safely be sent to the user without compromising
     62        // security.
     63        reason string
     64}
     65
     66func (err *authError) Error() string {
     67        return err.err.Error()
     68}
     69
     70func (err *authError) Unwrap() error {
     71        return err.err
     72}
     73
     74// authErrorReason returns the user-friendly reason of an authentication
     75// failure.
     76func authErrorReason(err error) string {
     77        if authErr, ok := err.(*authError); ok {
     78                return authErr.reason
     79        } else {
     80                return "Authentication failed"
     81        }
     82}
     83
     84func newInvalidUsernameOrPasswordError(err error) error {
     85        return &authError{
     86                err:    err,
     87                reason: "Invalid username or password",
     88        }
     89}
    6190
    6291func parseBouncerNetID(subcommand, s string) (int64, error) {
     
    699728
    700729                if err := dc.authenticate(ctx, credentials.plainUsername, credentials.plainPassword); err != nil {
    701                         dc.logger.Printf("SASL authentication error: %v", err)
     730                        dc.logger.Printf("SASL authentication error for user %q: %v", credentials.plainUsername, err)
    702731                        dc.endSASL(&irc.Message{
    703732                                Prefix:  dc.srv.prefix(),
    704733                                Command: irc.ERR_SASLFAIL,
    705                                 Params:  []string{"Authentication failed"},
     734                                Params:  []string{dc.nick, authErrorReason(err)},
    706735                        })
    707736                        break
     
    11491178        u, err := dc.srv.db.GetUser(ctx, username)
    11501179        if err != nil {
    1151                 dc.logger.Printf("failed authentication for %q: user not found: %v", username, err)
    1152                 return errAuthFailed
     1180                return newInvalidUsernameOrPasswordError(fmt.Errorf("user not found: %w", err))
    11531181        }
    11541182
    11551183        // Password auth disabled
    11561184        if u.Password == "" {
    1157                 return errAuthFailed
     1185                return newInvalidUsernameOrPasswordError(fmt.Errorf("password auth disabled"))
    11581186        }
    11591187
    11601188        err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
    11611189        if err != nil {
    1162                 dc.logger.Printf("failed authentication for %q: wrong password: %v", username, err)
    1163                 return errAuthFailed
     1190                return newInvalidUsernameOrPasswordError(fmt.Errorf("wrong password"))
    11641191        }
    11651192
    11661193        dc.user = dc.srv.getUser(username)
    11671194        if dc.user == nil {
    1168                 dc.logger.Printf("failed authentication for %q: user not active", username)
    1169                 return errAuthFailed
     1195                return fmt.Errorf("user not active")
    11701196        }
    11711197        dc.clientName = clientName
     
    11911217        if dc.user == nil {
    11921218                if err := dc.authenticate(ctx, dc.rawUsername, password); err != nil {
    1193                         return err
     1219                        dc.logger.Printf("PASS authentication error for user %q: %v", dc.rawUsername, err)
     1220                        return ircError{&irc.Message{
     1221                                Command: irc.ERR_PASSWDMISMATCH,
     1222                                Params:  []string{"*", authErrorReason(err)},
     1223                        }}
    11941224                }
    11951225        }
Note: See TracChangeset for help on using the changeset viewer.