Use bcryt to store password instead of custom HMAC
This commit is contained in:
parent
54ac261b64
commit
64661d3d7d
1
go.mod
1
go.mod
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
ALTER TABLE users
|
||||
DROP COLUMN salt;
|
||||
ALTER TABLE users
|
||||
MODIFY COLUMN password VARBINARY(255);
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue