Commit 35e1aa5a authored by David Venhoek's avatar David Venhoek Committed by Sietse Ringers
Browse files

Added pin check limiting to keyshareServerCore.

parent 09dbf0d3
......@@ -13,9 +13,13 @@ var (
)
type KeyshareDB interface {
NewUser(user KeyshareUser) error
User(username string) (KeyshareUser, error)
UpdateUser(user KeyshareUser) error
NewUser(user *KeyshareUser) error
User(username string) (*KeyshareUser, error)
UpdateUser(user *KeyshareUser) error
// Reserve returns (allow, tries, wait, error)
ReservePincheck(user *KeyshareUser) (bool, int, int, error)
ClearPincheck(user *KeyshareUser) error
}
type KeyshareUser struct {
......@@ -32,7 +36,7 @@ func NewMemoryDatabase() KeyshareDB {
return &keyshareMemoryDB{users: map[string]keyshareCore.EncryptedKeysharePacket{}}
}
func (db *keyshareMemoryDB) User(username string) (KeyshareUser, error) {
func (db *keyshareMemoryDB) User(username string) (*KeyshareUser, error) {
// Ensure access to database is single-threaded
db.lock.Lock()
defer db.lock.Unlock()
......@@ -40,12 +44,12 @@ func (db *keyshareMemoryDB) User(username string) (KeyshareUser, error) {
// Check and fetch user data
data, ok := db.users[username]
if !ok {
return KeyshareUser{}, ErrUserNotFound
return nil, ErrUserNotFound
}
return KeyshareUser{Username: username, Coredata: data}, nil
return &KeyshareUser{Username: username, Coredata: data}, nil
}
func (db *keyshareMemoryDB) NewUser(user KeyshareUser) error {
func (db *keyshareMemoryDB) NewUser(user *KeyshareUser) error {
// Ensure access to database is single-threaded
db.lock.Lock()
defer db.lock.Unlock()
......@@ -59,7 +63,7 @@ func (db *keyshareMemoryDB) NewUser(user KeyshareUser) error {
return nil
}
func (db *keyshareMemoryDB) UpdateUser(user KeyshareUser) error {
func (db *keyshareMemoryDB) UpdateUser(user *KeyshareUser) error {
// Ensure access to database is single-threaded
db.lock.Lock()
defer db.lock.Unlock()
......@@ -72,3 +76,13 @@ func (db *keyshareMemoryDB) UpdateUser(user KeyshareUser) error {
db.users[user.Username] = user.Coredata
return nil
}
func (db *keyshareMemoryDB) ReservePincheck(user *KeyshareUser) (bool, int, int, error) {
// Since this is a testing DB, implementing anything more than always allow creates hastle
return false, 1, 0, nil
}
func (db *keyshareMemoryDB) ClearPincheck(user *KeyshareUser) error {
// Since this is a testing DB, implementing anything more than always allow creates hastle
return nil
}
......@@ -137,7 +137,7 @@ func (s *Server) handleCommitments(w http.ResponseWriter, r *http.Request) {
return
}
// TODO: block check
// Generate commitments
commitments, commitId, err := s.core.GenerateCommitments(user.Coredata, authorization, keys)
if err != nil {
s.conf.Logger.WithField("error", err).Warn("Could not generate commitments for request")
......@@ -231,6 +231,7 @@ func (s *Server) handleValidate(w http.ResponseWriter, r *http.Request) {
username := r.Header.Get("X-IRMA-Keyshare-Username")
authorization := r.Header.Get("Authorization")
// Fetch user
user, err := s.db.User(username)
if err != nil {
s.conf.Logger.WithFields(logrus.Fields{"username": username, "error": err}).Warn("Could not find user in db")
......@@ -238,8 +239,7 @@ func (s *Server) handleValidate(w http.ResponseWriter, r *http.Request) {
return
}
// TODO: Block check
// Validate jwt
err = s.core.ValidateJWT(user.Coredata, authorization)
if err != nil {
server.WriteJson(w, &keyshareAuthorization{Status: "expired", Candidates: []string{"pin"}})
......@@ -272,13 +272,33 @@ func (s *Server) handleVerifyPin(w http.ResponseWriter, r *http.Request) {
return
}
// And verify pin
// TODO: Count tries, deal with (temp) block
jwtt, err := s.core.ValidatePin(user.Coredata, msg.Pin, msg.Username)
// And verify pin (checking that we are allowed to do this)
ok, tries, wait, err := s.db.ReservePincheck(user)
if err != nil {
fmt.Println(err)
server.WriteJson(w, keysharePinStatus{Status: "failure", Message: err.Error()})
s.conf.Logger.WithField("error", err).Error("Could not reserve pin check slot")
server.WriteError(w, server.ErrorInternal, err.Error())
return
}
if !ok {
server.WriteJson(w, keysharePinStatus{Status: "error", Message: fmt.Sprintf("%v", wait)})
return
}
jwtt, err := s.core.ValidatePin(user.Coredata, msg.Pin, msg.Username)
if err == keyshareCore.ErrInvalidPin {
if tries == 0 {
server.WriteJson(w, keysharePinStatus{Status: "error", Message: fmt.Sprintf("%v", wait)})
} else {
server.WriteJson(w, keysharePinStatus{Status: "failure", Message: fmt.Sprintf("%v", tries)})
}
} else if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not validate pin")
server.WriteError(w, server.ErrorInternal, err.Error())
} else {
err = s.db.ClearPincheck(user)
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not reset users pin check logic")
// Do not send to user
}
server.WriteJson(w, keysharePinStatus{Status: "success", Message: jwtt})
}
}
......@@ -307,12 +327,35 @@ func (s *Server) handleChangePin(w http.ResponseWriter, r *http.Request) {
return
}
// And change pin (TODO: count and block on pin checks)
user.Coredata, err = s.core.ChangePin(user.Coredata, msg.OldPin, msg.NewPin)
// And change pin, checking that we are allowed to do this
ok, tries, wait, err := s.db.ReservePincheck(user)
if err != nil {
server.WriteJson(w, keysharePinStatus{Status: "failure", Message: err.Error()})
s.conf.Logger.WithField("error", err).Error("Could not reserve pin check slot")
server.WriteError(w, server.ErrorInternal, err.Error())
return
}
if !ok {
server.WriteJson(w, keysharePinStatus{Status: "error", Message: fmt.Sprintf("%v", wait)})
return
}
user.Coredata, err = s.core.ChangePin(user.Coredata, msg.OldPin, msg.NewPin)
if err == keyshareCore.ErrInvalidPin {
if tries == 0 {
server.WriteJson(w, keysharePinStatus{Status: "error", Message: fmt.Sprintf("%v", wait)})
} else {
server.WriteJson(w, keysharePinStatus{Status: "failure", Message: fmt.Sprintf("%v", tries)})
}
return
} else if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not change pin")
server.WriteError(w, server.ErrorInternal, err.Error())
return
}
err = s.db.ClearPincheck(user)
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not reset users pin check logic")
// Do not send to user
}
// Write user back
err = s.db.UpdateUser(user)
......@@ -350,7 +393,7 @@ func (s *Server) handleRegister(w http.ResponseWriter, r *http.Request) {
server.WriteError(w, server.ErrorInvalidRequest, err.Error())
return
}
err = s.db.NewUser(KeyshareUser{Username: username, Coredata: coredata})
err = s.db.NewUser(&KeyshareUser{Username: username, Coredata: coredata})
if err != nil {
s.conf.Logger.WithField("error", err).Error("Could not store new user in database")
server.WriteError(w, server.ErrorInternal, err.Error())
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment