示例#1
0
// Check that verify password works ok: it return true only if the following requiremnts are OK:
// The password is equal to the current password and the password is not expired
func Test_VerifyPwd(t *testing.T) {
	uPwd, err := NewUserPwd(defaultPassword, defaultSaltStr)
	if err != nil {
		t.Error("Test fail, can't initialized user password structure, error:", err)
		t.FailNow()
	}
	tPwd, _ := salt.GenerateSaltedPassword(defaultPassword, MinPasswordLength, MaxPasswordLength, uPwd.Salt, -1)
	pwd := GetHashedPwd(tPwd)
	err = uPwd.IsPasswordMatch(pwd)
	if err != nil {
		t.Errorf("Test fail: password '%v' was not accepted but it is the same as the current password, %v, error: %v", pwd, uPwd, err)
	}
	tPwd, _ = salt.GenerateSaltedPassword([]byte(string(pwd)+"a"), MinPasswordLength, MaxPasswordLength, uPwd.Salt, -1)
	wrongPwd := GetHashedPwd(tPwd)
	err = uPwd.IsPasswordMatch(wrongPwd)
	if err == nil {
		t.Errorf("Test fail: password '%v' was approved but it is different from the current password, %v", wrongPwd, uPwd)
	}
	for i := -2; i < 3; i++ {
		if i == 0 {
			continue
		}
		uPwd.Expiration = time.Now().Add(time.Duration(i) * time.Second)
		err = uPwd.IsPasswordMatch(pwd)
		if err == nil && i <= 0 {
			t.Errorf("Test fail: password was approved but it is not valid (expired, time now %v), %v", time.Now(), uPwd.Expiration)
		} else if err != nil && i > 0 {
			t.Errorf("Test fail: password was not approved but it valid (time now %v), %v", time.Now(), uPwd.Expiration)
		}
	}
}
示例#2
0
func (p pwdRestful) restVerifyPassword(request *restful.Request, response *restful.Response) {
	var secret secretData
	err := request.ReadEntity(&secret)
	tPwd, _ := salt.GenerateSaltedPassword([]byte(secret.Password), password.MinPasswordLength, password.MaxPasswordLength, p.saltStr, -1)
	pass := password.GetHashedPwd(tPwd)
	if err != nil {
		p.setError(response, http.StatusBadRequest, err)
		return
	}
	data := p.getPwdData(request, response)
	if data == nil {
		return
	}
	err = data.IsPasswordMatch(pass)
	ok := true
	if err != nil {
		ok = false
	}
	res := cr.Match{Match: ok, Message: cr.NoMessageStr}
	if ok == false && err != nil {
		res.Message = fmt.Sprintf("%v", err)
	}
	response.WriteEntity(res)
	response.WriteHeader(http.StatusOK)
}
示例#3
0
func (p pwdRestful) restUpdatePassword(request *restful.Request, response *restful.Response) {
	var secrets cr.UpdateSecret
	name := request.PathParameter(userIdParam)
	err := request.ReadEntity(&secrets)
	if err != nil {
		p.setError(response, http.StatusBadRequest, err)
		return
	}
	data := p.getPwdData(request, response)
	if data == nil {
		return
	}
	tPwd, _ := salt.GenerateSaltedPassword([]byte(secrets.OldPassword), password.MinPasswordLength, password.MaxPasswordLength, p.saltStr, -1)
	pass := password.GetHashedPwd(tPwd)
	if err != nil {
		p.setError(response, http.StatusBadRequest, err)
		return
	}
	_, err = data.UpdatePassword(pass, []byte(secrets.NewPassword))
	if err != nil {
		p.setError(response, http.StatusBadRequest, err)
		return
	}
	response.WriteHeader(http.StatusCreated)
	response.WriteEntity(p.getUrlPath(request, name))
}
示例#4
0
// Update the password, it's expioration time and it's state (is it a one-time-password or a regular one)
func (u *UserPwd) updatePasswordHandler(currentPwd []byte, pwd []byte, expiration time.Time, oneTimePwd bool) ([]byte, error) {
	pLock.Lock()
	defer pLock.Unlock()

	err := isPwdLengthValid(pwd)
	if err != nil {
		return nil, err
	}
	err = u.isPasswordMatchHandler(currentPwd, true)
	if err != nil {
		return nil, err
	}
	tmpPwd, err := salt.GenerateSaltedPassword(pwd, MinPasswordLength, MaxPasswordLength, u.Salt, -1)
	if err != nil {
		return nil, fmt.Errorf("Error while generating the new password: %v", err)
	}
	err = u.IsNewPwdValid(tmpPwd)
	if err != nil {
		return nil, err
	}
	newPwd := GetHashedPwd(tmpPwd)
	copy(u.OldPasswords[1:], u.OldPasswords[:])
	u.OldPasswords[0] = u.Password
	u.Password = newPwd
	u.Expiration = expiration
	u.ErrorsCounter = 0
	u.SetOneTimePwd(oneTimePwd)
	return newPwd, nil
}
// This example shows how to generate a saltetd password from a given password and default salt
func ExampleGenerateSaltedPassword() {
	pass := "******"
	res, err := salt.GenerateSaltedPassword([]byte(pass), minSecretLen, maxSecretLen, BasicSalt, -1)
	if err != nil {
		fmt.Println("GenerateSaltedPassword failed, error:", err)
	} else {
		fmt.Printf("* Generate basic salted password from a given password: '******', using the default parameters (sha1, show full password, 1 iteration and random salt: %v) is: %v", pass, BasicSalt, res)
	}
}
// Check if a given password matches the curent password
// Note that the passwords are stored after hashing and not as clear text
// If the passwords don't match, a 1 second delay will be used before the
// next attempt, in order to prevent brute force entry attempts
func (u AmUserInfo) IsPasswordMatch(pwd []byte) error {
	saltedPwd, _ := salt.GenerateSaltedPassword([]byte(pwd), password.MinPasswordLength, password.MaxPasswordLength, u.Pwd.Salt, -1)
	tPwd := password.GetHashedPwd(saltedPwd)
	err := u.Pwd.IsPasswordMatch(tPwd)
	// on error throttle for 1 second, reset the error counter
	if err != nil {
		time.Sleep(1 * time.Second)
		u.Pwd.ErrorsCounter = 0 // the throttling is enougth
		return err
	}
	return nil
}
// Generate a new secure storage minimal file that includes the root user with
// basic Account Management: the root user privilege and password
func createBasicFile(stFilePath string, name string, pass string, key []byte) {
	saltStr, _ := salt.GetRandomSalt(saltLen)
	_, err := salt.GenerateSaltedPassword([]byte(pass), password.MinPasswordLength, password.MaxPasswordLength, saltStr, -1)
	if err != nil {
		log.Fatalf("Error: can't generate salted password for '%v' user, error: %v", name, err)
	}
	ul := en.NewEntityManager()
	ul.AddUser(name)
	amUser, _ := am.NewUserAm(am.SuperUserPermission, []byte(pass), saltStr)
	ul.AddPropertyToEntity(name, stc.AmPropertyName, amUser)
	ul.StoreInfo(stFilePath, key)
}
示例#8
0
// Generate a new UserPwd for a given password
// The generated password is with a default expiration time
func NewUserPwd(pwd []byte, saltData []byte) (*UserPwd, error) {
	err := isPwdLengthValid(pwd)
	if err != nil {
		return nil, err
	}
	newPwd, err := salt.GenerateSaltedPassword(pwd, MinPasswordLength, MaxPasswordLength, saltData, -1)
	if err != nil {
		return nil, err
	}
	setPwd := GetHashedPwd(newPwd)
	return &UserPwd{setPwd, saltData, getNewDefaultPasswordExpirationTime(), 0, defaultOneTimePwd, [defaultNumberOfOldPasswords][]byte{}}, nil
}
示例#9
0
// Verify that the password is OK, after reset password, the old password
// it not OK, the new temporary password is OK only once
// and after password update, the new password is valid
func Test_ResetPassword(t *testing.T) {
	user, _ := NewUserPwd(defaultPassword, defaultSaltStr)
	tPwd, _ := salt.GenerateSaltedPassword(defaultPassword, MinPasswordLength, MaxPasswordLength, user.Salt, -1)
	pass := GetHashedPwd(tPwd)
	err := user.IsPasswordMatch(pass)
	if err != nil {
		t.Errorf("Test fail: correct password: '******', return an error: %v", pass, err)
	}
	tmpPwd, err := user.ResetPasword()
	if err != nil {
		t.Errorf("Test fail: Reset password fail, error: %v", err)
	}
	tPwd, _ = salt.GenerateSaltedPassword(tmpPwd, MinPasswordLength, MaxPasswordLength, user.Salt, -1)
	newPwd := GetHashedPwd(tPwd)
	err = user.IsPasswordMatch(pass)
	if err == nil {
		t.Errorf("Test fail: Old password: '******' accepted", pass)
	}
	err = user.IsPasswordMatch(newPwd)
	if err != nil {
		t.Errorf("Test fail: The new automatic generated password: '******' was not accepted, error: %v", newPwd, err)
	}
	err = user.IsPasswordMatch(pass)
	if err == nil {
		t.Errorf("Test fail: The one time pwd: '%v' accepted twice", newPwd)
	}
	for i := 0; i < 3; i++ {
		pass = []byte(string(pass) + "a")
		expiration := time.Now().Add(time.Duration(defaultOneTimePwdExpirationMinutes) * time.Second * 60)
		newPwd, err := user.UpdatePasswordAfterReset(user.Password, pass, expiration)
		if err != nil {
			t.Errorf("Test fail: can't use the new password: '******' (%v), return an error: %v", pass, string(pass), err)
		} else {
			err := user.IsPasswordMatch(newPwd)
			if err != nil {
				t.Errorf("Test fail: correct password: '******' (%v), return an error: %v", newPwd, string(pass), err)
			}
		}
	}
}
示例#10
0
// Check that one time password can be used exctly once
func Test_UseOfOneTimePwd(t *testing.T) {
	user, err := NewUserPwd(defaultPassword, defaultSaltStr)
	if err != nil {
		t.Error("Test fail, can't initialized user password structure, error:", err)
		t.FailNow()
	}
	tPwd, _ := salt.GenerateSaltedPassword(defaultPassword, MinPasswordLength, MaxPasswordLength, user.Salt, -1)
	pwd := GetHashedPwd(tPwd)
	user.SetOneTimePwd(true)
	err = user.IsPasswordMatch(pwd)
	if err != nil {
		t.Errorf("Test fail: password '%v' was not accepted but it is the same as the current password, %v, current time: %v, error: %v", pwd, user, time.Now(), err)
	}
	err = user.IsPasswordMatch(pwd)
	if err == nil {
		t.Errorf("Test fail: password '%v' accepted but it was a one time password, and it was already used, %v, current time: %v", pwd, user, time.Now())
	}
}
// Example of how to use the reset password function:
// This function resets the current password,
// selects a new password with short expiration time
// and lets the user use it exactly once
func ExampleUserPwd_ResetPasword() {
	id := "User1"
	pwd := []byte("a1b2c3d")

	saltStr, _ := salt.GetRandomSalt(10)
	userPwd, _ := password.NewUserPwd(pwd, saltStr)
	tmpPwd, _ := userPwd.ResetPasword()
	tPwd, _ := salt.GenerateSaltedPassword(tmpPwd, 1, 100, saltStr, -1)
	newPwd := password.GetHashedPwd(tPwd)
	err := userPwd.IsPasswordMatch(newPwd)
	if err != nil {
		fmt.Printf("Check of newly generated password: '******' for user: %v failed, error: %v\n", newPwd, id, err)
	} else {
		fmt.Printf("Entity %v, after reseting password '%v' verified successfuly\n", id, newPwd)
	}
	err = userPwd.IsPasswordMatch(newPwd)
	if err == nil {
		fmt.Printf("Error: Newly generated password: '******' could be used only once\n", newPwd)
	} else {
		fmt.Printf("Newly generated password: '******', for entity: %v, can only be used once\n", newPwd, id)
	}
}
// Example of how to use the password.
// 1. Create a new password.
// 2. Verify that the initial password is set correctly
// 3. Change the user's password
// 4. Verify that the old password is not valid anymore
// 5. Verify that the new password is valid
// 6. Verify that the old password can't be used any more
//     (at least not as long as it remains in the old passwords list)
func ExampleUserPwd() {
	id := "User-1"
	pwd := []byte("a1b2c3d")
	saltStr, _ := salt.GetRandomSalt(8)

	userPwd, _ := password.NewUserPwd(pwd, saltStr)
	tPwd, _ := salt.GenerateSaltedPassword(pwd, minPasswordLength, maxPasswordLength, saltStr, -1)
	newPwd := password.GetHashedPwd(tPwd)
	err := userPwd.IsPasswordMatch(newPwd)
	if err != nil {
		fmt.Println("Ravid: error", err)
	}
	userNewPwd := []byte(string(pwd) + "a")
	newPwd, err = userPwd.UpdatePassword(userPwd.Password, userNewPwd)
	if err != nil {
		fmt.Printf("Password update for user %v to new password '%v' (%v) failed, error: %v\n", id, newPwd, string(userNewPwd), err)
	} else {
		fmt.Printf("User: '******', updated password to '%v' (%v)\n", id, newPwd, string(userNewPwd))
	}
	err = userPwd.IsPasswordMatch(newPwd)
	if err != nil {
		fmt.Printf("Check of the new password: '******' (%v) for user: %v failed, error: %v\n", newPwd, string(userNewPwd), id, err)
	} else {
		fmt.Printf("User: '******', new password '%v' (%v) verified successfuly\n", id, newPwd, string(userNewPwd))
	}
	err = userPwd.IsPasswordMatch(pwd)
	if err == nil {
		fmt.Printf("Error: Old password: '******' (%v) for user: %v accepted\n", pwd, string(pwd), id)
	} else {
		fmt.Printf("User: '******', Note that the old password '%v' (%v) can't be used anymore\n", id, pwd, string(pwd))
	}
	newPwd, err = userPwd.UpdatePassword(userPwd.Password, pwd)
	if err == nil {
		fmt.Printf("Error: Password '%v' (typed password %v) for user %v was alredy used\n", newPwd, string(pwd), id)
	} else {
		fmt.Printf("Entity: '%v', Note that the old password (entered password) %v as it was already used\n", id, string(pwd))
	}
}
示例#13
0
func (l amRestful) restUpdatePwd(request *restful.Request, response *restful.Response) {
	var secrets cr.UpdateSecret

	err := request.ReadEntity(&secrets)
	if err != nil {
		l.setError(response, http.StatusBadRequest, err)
		return
	}
	userName := request.PathParameter(userIdParam)
	data := l.getAM(request, response, userName)
	if data == nil {
		return
	}
	tPwd, err := salt.GenerateSaltedPassword([]byte(secrets.OldPassword), password.MinPasswordLength, password.MaxPasswordLength, data.Pwd.Salt, -1)
	oldPwd := password.GetHashedPwd(tPwd)
	err = data.UpdateUserPwd(userName, oldPwd, []byte(secrets.NewPassword))
	if err != nil {
		l.setError(response, http.StatusBadRequest, err)
		return
	}
	response.WriteHeader(http.StatusCreated)
	response.WriteEntity(l.getUrlPath(request, userName))
}
示例#14
0
func getSaltedPass(secret, saltData []byte) []byte {
	pass, _ := salt.GenerateSaltedPassword(secret, minSecretLen, maxSecretLen, saltData, SecretLen)
	return bytes.Replace(pass, []byte{'0'}, []byte{'a'}, -1)
}