Stop accessing user data in downstreamConn.authenticate

This becomes racy once user.Password is updated on-the-fly.

git-svn-id: file:///srv/svn/repo/suika/trunk@173 f0ae65fe-ee39-954e-97ec-027ff2717ef4
This commit is contained in:
contact 2020-03-27 21:38:38 +00:00
parent ff41376348
commit a17e0acde2
2 changed files with 27 additions and 8 deletions

15
db.go
View File

@ -106,6 +106,21 @@ func (db *DB) ListUsers() ([]User, error) {
return users, nil
}
func (db *DB) GetUser(username string) (*User, error) {
db.lock.RLock()
defer db.lock.RUnlock()
user := &User{Username: username}
var password *string
row := db.db.QueryRow("SELECT password FROM User WHERE username = ?", username)
if err := row.Scan(&password); err != nil {
return nil, err
}
user.Password = fromStringPtr(password)
return user, nil
}
func (db *DB) CreateUser(user *User) error {
db.lock.Lock()
defer db.lock.Unlock()

View File

@ -586,19 +586,23 @@ func unmarshalUsername(rawUsername string) (username, network string) {
func (dc *downstreamConn) authenticate(username, password string) error {
username, networkName := unmarshalUsername(username)
u := dc.srv.getUser(username)
if u == nil {
dc.logger.Printf("failed authentication for %q: unknown username", username)
return errAuthFailed
}
err := bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
u, err := dc.srv.db.GetUser(username)
if err != nil {
dc.logger.Printf("failed authentication for %q: %v", username, err)
return errAuthFailed
}
dc.user = u
err = bcrypt.CompareHashAndPassword([]byte(u.Password), []byte(password))
if err != nil {
dc.logger.Printf("failed authentication for %q: %v", username, err)
return errAuthFailed
}
dc.user = dc.srv.getUser(username)
if dc.user == nil {
dc.logger.Printf("failed authentication for %q: user not active", username)
return errAuthFailed
}
dc.networkName = networkName
return nil
}