1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

chore: remove legacy support for md5 hashed passwords

chore: remove password from encoded cookie content as not used anyway
This commit is contained in:
Ferdinand Mütsch 2021-01-31 14:34:54 +01:00
parent 105f96ff72
commit 979549448c
4 changed files with 12 additions and 47 deletions

View File

@ -2,9 +2,7 @@ package middlewares
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"github.com/emvi/logbuch"
conf "github.com/muety/wakapi/config" conf "github.com/muety/wakapi/config"
"github.com/muety/wakapi/models" "github.com/muety/wakapi/models"
"github.com/muety/wakapi/services" "github.com/muety/wakapi/services"
@ -78,32 +76,18 @@ func (m *AuthenticateMiddleware) tryGetUserByApiKey(r *http.Request) (*models.Us
} }
func (m *AuthenticateMiddleware) tryGetUserByCookie(r *http.Request) (*models.User, error) { func (m *AuthenticateMiddleware) tryGetUserByCookie(r *http.Request) (*models.User, error) {
login, err := utils.ExtractCookieAuth(r, m.config) username, err := utils.ExtractCookieAuth(r, m.config)
if err != nil { if err != nil {
return nil, err return nil, err
} }
user, err := m.userSrvc.GetUserById(login.Username) user, err := m.userSrvc.GetUserById(*username)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !CheckAndMigratePassword(user, login, m.config.Security.PasswordSalt, &m.userSrvc) { // no need to check password here, as securecookie decoding will fail anyway,
return nil, errors.New("invalid password") // if cookie is not properly signed
}
return user, nil return user, nil
} }
// migrate old md5-hashed passwords to new salted bcrypt hashes for backwards compatibility
func CheckAndMigratePassword(user *models.User, login *models.Login, salt string, userServiceRef *services.IUserService) bool {
if utils.IsMd5(user.Password) {
if utils.CompareMd5(user.Password, login.Password, "") {
logbuch.Info("migrating old md5 password to new bcrypt format for user '%s'", user.ID)
(*userServiceRef).MigrateMd5Password(user, login)
return true
}
return false
}
return utils.CompareBcrypt(user.Password, login.Password, salt)
}

View File

@ -4,10 +4,10 @@ import (
"fmt" "fmt"
"github.com/gorilla/mux" "github.com/gorilla/mux"
conf "github.com/muety/wakapi/config" conf "github.com/muety/wakapi/config"
"github.com/muety/wakapi/middlewares"
"github.com/muety/wakapi/models" "github.com/muety/wakapi/models"
"github.com/muety/wakapi/models/view" "github.com/muety/wakapi/models/view"
"github.com/muety/wakapi/services" "github.com/muety/wakapi/services"
"github.com/muety/wakapi/utils"
"net/http" "net/http"
"time" "time"
) )
@ -76,14 +76,13 @@ func (h *LoginHandler) PostLogin(w http.ResponseWriter, r *http.Request) {
return return
} }
// TODO: depending on middleware package here is a hack if !utils.CompareBcrypt(user.Password, login.Password, h.config.Security.PasswordSalt) {
if !middlewares.CheckAndMigratePassword(user, &login, h.config.Security.PasswordSalt, &h.userSrvc) {
w.WriteHeader(http.StatusUnauthorized) w.WriteHeader(http.StatusUnauthorized)
templates[conf.LoginTemplate].Execute(w, h.buildViewModel(r).WithError("invalid credentials")) templates[conf.LoginTemplate].Execute(w, h.buildViewModel(r).WithError("invalid credentials"))
return return
} }
encoded, err := h.config.Security.SecureCookie.Encode(models.AuthCookieKey, login) encoded, err := h.config.Security.SecureCookie.Encode(models.AuthCookieKey, login.Username)
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
templates[conf.LoginTemplate].Execute(w, h.buildViewModel(r).WithError("internal server error")) templates[conf.LoginTemplate].Execute(w, h.buildViewModel(r).WithError("internal server error"))

View File

@ -113,7 +113,7 @@ func (h *SettingsHandler) PostCredentials(w http.ResponseWriter, r *http.Request
Username: user.ID, Username: user.ID,
Password: user.Password, Password: user.Password,
} }
encoded, err := h.config.Security.SecureCookie.Encode(models.AuthCookieKey, login) encoded, err := h.config.Security.SecureCookie.Encode(models.AuthCookieKey, login.Username)
if err != nil { if err != nil {
w.WriteHeader(http.StatusInternalServerError) w.WriteHeader(http.StatusInternalServerError)
templates[conf.SettingsTemplate].Execute(w, h.buildViewModel(r).WithError("internal server error")) templates[conf.SettingsTemplate].Execute(w, h.buildViewModel(r).WithError("internal server error"))

View File

@ -1,9 +1,7 @@
package utils package utils
import ( import (
"crypto/md5"
"encoding/base64" "encoding/base64"
"encoding/hex"
"errors" "errors"
"github.com/muety/wakapi/config" "github.com/muety/wakapi/config"
"github.com/muety/wakapi/models" "github.com/muety/wakapi/models"
@ -46,21 +44,17 @@ func ExtractBearerAuth(r *http.Request) (key string, err error) {
return string(keyBytes), err return string(keyBytes), err
} }
func ExtractCookieAuth(r *http.Request, config *config.Config) (login *models.Login, err error) { func ExtractCookieAuth(r *http.Request, config *config.Config) (username *string, err error) {
cookie, err := r.Cookie(models.AuthCookieKey) cookie, err := r.Cookie(models.AuthCookieKey)
if err != nil { if err != nil {
return nil, errors.New("missing authentication") return nil, errors.New("missing authentication")
} }
if err := config.Security.SecureCookie.Decode(models.AuthCookieKey, cookie.Value, &login); err != nil { if err := config.Security.SecureCookie.Decode(models.AuthCookieKey, cookie.Value, &username); err != nil {
return nil, errors.New("invalid parameters") return nil, errors.New("cookie is invalid")
} }
return login, nil return username, nil
}
func IsMd5(hash string) bool {
return md5Regex.Match([]byte(hash))
} }
func CompareBcrypt(wanted, actual, pepper string) bool { func CompareBcrypt(wanted, actual, pepper string) bool {
@ -69,11 +63,6 @@ func CompareBcrypt(wanted, actual, pepper string) bool {
return err == nil return err == nil
} }
// deprecated, only here for backwards compatibility
func CompareMd5(wanted, actual, pepper string) bool {
return HashMd5(actual, pepper) == wanted
}
func HashBcrypt(plain, pepper string) (string, error) { func HashBcrypt(plain, pepper string) (string, error) {
plainPepperedPassword := []byte(strings.TrimSpace(plain) + pepper) plainPepperedPassword := []byte(strings.TrimSpace(plain) + pepper)
bytes, err := bcrypt.GenerateFromPassword(plainPepperedPassword, bcrypt.DefaultCost) bytes, err := bcrypt.GenerateFromPassword(plainPepperedPassword, bcrypt.DefaultCost)
@ -82,10 +71,3 @@ func HashBcrypt(plain, pepper string) (string, error) {
} }
return "", err return "", err
} }
func HashMd5(plain, pepper string) string {
plainPepperedPassword := []byte(strings.TrimSpace(plain) + pepper)
hash := md5.Sum(plainPepperedPassword)
hashStr := hex.EncodeToString(hash[:])
return hashStr
}