Ejemplo n.º 1
0
// checkPass verifies that the given user exists and that the password matches.
func checkPass(username, pass string, ip net.Addr) (user *world.User, err error) {
	if world.FindPlayer(username) != nil {
		return nil, ErrDupe
	}
	hash, err := db.Password(username)
	if err != nil {
		return nil, err
	}

	passb := []byte(pass)
	if hash == nil {
		// User does not exist. Fake out the time we would otherwise take to run
		// the hash.  Ignore the error, we really only care about sucking up
		// some CPU cycles here.
		_ = bcrypt.CompareHashAndPassword(fakehash, passb)
		return nil, ErrAuth
	}

	err = bcrypt.CompareHashAndPassword(hash, passb)
	if err == bcrypt.ErrMismatchedHashAndPassword {
		return nil, ErrAuth
	}
	if err != nil {
		return nil, err
	}

	cost, err := bcrypt.Cost(hash)
	if err != nil {
		return nil, err
	}

	// Handle bcrypt cost change, rehash with new cost.
	if cost != bcryptCost {
		hash, err = bcrypt.GenerateFromPassword(passb, bcryptCost)
		if err != nil {
			return nil, err
		}
	}

	// Login successful, update info.
	if err := db.SaveUser(username, ip, hash); err != nil {
		return nil, err
	}

	return &world.User{Username: username, IP: ip}, nil
}
Ejemplo n.º 2
0
// createUser creates the user if it does not exist.  If it does exist,
// createUser will return ErrExists.
func createUser(username, pw string, ip net.Addr) (user *world.User, err error) {
	// do the expensive hash outside the critical section!!
	hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcryptCost)
	if err != nil {
		return nil, err
	}

	exists, err := db.UserExists(username)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, ErrExists
	}

	if err := db.SaveUser(username, ip, hash); err != nil {
		return nil, err
	}
	user = &world.User{
		Username: username,
	}
	return user, nil
}