Use bcryt to store password instead of custom HMAC

This commit is contained in:
nemunaire 2020-05-23 18:41:04 +02:00
parent 54ac261b64
commit 64661d3d7d
5 changed files with 23 additions and 38 deletions

1
go.mod
View File

@ -8,5 +8,6 @@ require (
github.com/miekg/dns v1.1.29
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
github.com/syndtr/goleveldb v1.0.0
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
gopkg.in/ini.v1 v1.55.0 // indirect
)

View File

@ -32,26 +32,20 @@
package happydns
import (
"crypto/hmac"
"crypto/rand"
"crypto/sha512"
"time"
"golang.org/x/crypto/bcrypt"
)
type User struct {
Id int64
Email string
Password []byte
Salt []byte
RegistrationTime *time.Time
}
type Users []*User
func GenPassword(password string, salt []byte) []byte {
return hmac.New(sha512.New512_224, []byte(password)).Sum(salt)
}
func NewUser(email string, password string) (u *User, err error) {
t := time.Now()
@ -66,31 +60,12 @@ func NewUser(email string, password string) (u *User, err error) {
return
}
// DefinePassword computes the expected hash for the given password and also
// renew the User's Salt.
func (u *User) DefinePassword(password string) error {
// Renew salt
u.Salt = make([]byte, 64)
if _, err := rand.Read(u.Salt); err != nil {
return err
}
func (u *User) DefinePassword(password string) (err error) {
u.Password, err = bcrypt.GenerateFromPassword([]byte(password), 0)
// Compute password hash
u.Password = GenPassword(password, u.Salt)
return nil
return
}
func (u *User) CheckAuth(password string) bool {
pass := GenPassword(password, u.Salt)
if len(pass) != len(u.Password) {
return false
} else {
for k := range pass {
if pass[k] != u.Password[k] {
return false
}
}
return true
}
return bcrypt.CompareHashAndPassword(u.Password, []byte(password)) == nil
}

View File

@ -2,7 +2,7 @@
package database // import "happydns.org/database"
const schemaVersion = 3
const schemaVersion = 4
var schemaRevisions = map[uint16]string{
1: `CREATE TABLE schema_version (
@ -63,5 +63,10 @@ ALTER TABLE zones
DROP COLUMN storage_facility;
RENAME TABLE zones TO domains;
`,
4: `ALTER TABLE users
DROP COLUMN salt;
ALTER TABLE users
MODIFY COLUMN password VARBINARY(255);
`,
}

View File

@ -0,0 +1,4 @@
ALTER TABLE users
DROP COLUMN salt;
ALTER TABLE users
MODIFY COLUMN password VARBINARY(255);

View File

@ -36,14 +36,14 @@ import (
)
func (s *MySQLStorage) GetUsers() (users happydns.Users, err error) {
if rows, errr := s.db.Query("SELECT id_user, email, password, salt, registration_time FROM users"); errr != nil {
if rows, errr := s.db.Query("SELECT id_user, email, password, registration_time FROM users"); errr != nil {
return nil, errr
} else {
defer rows.Close()
for rows.Next() {
var u happydns.User
if err = rows.Scan(&u.Id, &u.Email, &u.Password, &u.Salt, &u.RegistrationTime); err != nil {
if err = rows.Scan(&u.Id, &u.Email, &u.Password, &u.RegistrationTime); err != nil {
return
}
users = append(users, &u)
@ -58,13 +58,13 @@ func (s *MySQLStorage) GetUsers() (users happydns.Users, err error) {
func (s *MySQLStorage) GetUser(id int64) (u *happydns.User, err error) {
u = &happydns.User{}
err = s.db.QueryRow("SELECT id_user, email, password, salt, registration_time FROM users WHERE id_user=?", id).Scan(&u.Id, &u.Email, &u.Password, &u.Salt, &u.RegistrationTime)
err = s.db.QueryRow("SELECT id_user, email, password, registration_time FROM users WHERE id_user=?", id).Scan(&u.Id, &u.Email, &u.Password, &u.RegistrationTime)
return
}
func (s *MySQLStorage) GetUserByEmail(email string) (u *happydns.User, err error) {
u = &happydns.User{}
err = s.db.QueryRow("SELECT id_user, email, password, salt, registration_time FROM users WHERE email=?", email).Scan(&u.Id, &u.Email, &u.Password, &u.Salt, &u.RegistrationTime)
err = s.db.QueryRow("SELECT id_user, email, password, registration_time FROM users WHERE email=?", email).Scan(&u.Id, &u.Email, &u.Password, &u.RegistrationTime)
return
}
@ -75,7 +75,7 @@ func (s *MySQLStorage) UserExists(email string) bool {
}
func (s *MySQLStorage) CreateUser(u *happydns.User) error {
if res, err := s.db.Exec("INSERT INTO users (email, password, salt, registration_time) VALUES (?, ?, ?, ?)", u.Email, u.Password, u.Salt, u.RegistrationTime); err != nil {
if res, err := s.db.Exec("INSERT INTO users (email, password, registration_time) VALUES (?, ?, ?, ?)", u.Email, u.Password, u.RegistrationTime); err != nil {
return err
} else if sid, err := res.LastInsertId(); err != nil {
return err
@ -86,7 +86,7 @@ func (s *MySQLStorage) CreateUser(u *happydns.User) error {
}
func (s *MySQLStorage) UpdateUser(u *happydns.User) error {
_, err := s.db.Exec("UPDATE users SET email = ?, password = ?, salt = ?, registration_time = ? WHERE id_user = ?", u.Email, u.Password, u.Salt, u.RegistrationTime, u.Id)
_, err := s.db.Exec("UPDATE users SET email = ?, password = ?, registration_time = ? WHERE id_user = ?", u.Email, u.Password, u.RegistrationTime, u.Id)
return err
}