Manager: move worker password hasher into a struct + interface

Move the Worker password hashing/comparison functions into a struct, and
use it via an interface. This will make it easier to switch to different
hashing algorithms.

Even with a low number of iterations, BCrypt is quite slow. That's good for
security, but not for Flamenco Worker authentication -- the password is
more as "nice check to avoid accidentally reusing the same ID" than
something for security.
This commit is contained in:
Sybren A. Stüvel 2022-07-15 13:07:45 +02:00
parent 35fe0146d3
commit 0e4ed1c54d
2 changed files with 22 additions and 7 deletions

View File

@ -22,8 +22,28 @@ const (
var (
errAuthBad = errors.New("no such worker known")
passwordHasher = BCryptHasher{}
)
type WorkerPasswordHasher interface {
GenerateHashedPassword(password []byte) ([]byte, error)
CompareHashAndPassword(hashedPassword, password []byte) error
}
// BCryptHasher uses BCrypt to hash the worker passwords.
type BCryptHasher struct{}
func (h BCryptHasher) GenerateHashedPassword(password []byte) ([]byte, error) {
// The default BCrypt cost is made for important passwords. For Flamenco, the
// Worker password is not that important.
const bcryptCost = bcrypt.MinCost
return bcrypt.GenerateFromPassword(password, bcryptCost)
}
func (h BCryptHasher) CompareHashAndPassword(hashedPassword, password []byte) error {
return bcrypt.CompareHashAndPassword(hashedPassword, password)
}
// OpenAPI authentication function for authing workers.
// The worker will be fetched from the database and stored in the request context.
func WorkerAuth(ctx context.Context, authInfo *openapi3filter.AuthenticationInput, persist PersistenceService) error {
@ -49,7 +69,7 @@ func WorkerAuth(ctx context.Context, authInfo *openapi3filter.AuthenticationInpu
}
// Check the password.
err = bcrypt.CompareHashAndPassword([]byte(hashedSecret), []byte(p))
err = passwordHasher.CompareHashAndPassword([]byte(hashedSecret), []byte(p))
if err != nil {
logger.Warn().Str("username", u).Msg("authentication error")
return authInfo.NewError(errAuthBad)

View File

@ -13,7 +13,6 @@ import (
"github.com/labstack/echo/v4"
"github.com/rs/zerolog"
"golang.org/x/crypto/bcrypt"
"git.blender.org/flamenco/internal/manager/last_rendered"
"git.blender.org/flamenco/internal/manager/persistence"
@ -23,10 +22,6 @@ import (
"git.blender.org/flamenco/pkg/api"
)
// The default BCrypt cost is made for important passwords. For Flamenco, the
// Worker password is not that important.
const bcryptCost = bcrypt.MinCost
// RegisterWorker registers a new worker and stores it in the database.
func (f *Flamenco) RegisterWorker(e echo.Context) error {
logger := requestLogger(e)
@ -42,7 +37,7 @@ func (f *Flamenco) RegisterWorker(e echo.Context) error {
logger.Info().Str("name", req.Name).Msg("registering new worker")
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Secret), bcryptCost)
hashedPassword, err := passwordHasher.GenerateHashedPassword([]byte(req.Secret))
if err != nil {
logger.Warn().Err(err).Msg("error hashing worker password")
return sendAPIError(e, http.StatusBadRequest, "error hashing password")