func (*passwordSuite) TestAgentPasswordHash(c *gc.C) { seenValues := make(map[string]bool) for i := 0; i < 1000; i++ { password, err := utils.RandomPassword() c.Assert(err, gc.IsNil) c.Assert(seenValues[password], jc.IsFalse) seenValues[password] = true hashed := utils.AgentPasswordHash(password) c.Assert(hashed, gc.Not(gc.Equals), password) c.Assert(seenValues[hashed], jc.IsFalse) seenValues[hashed] = true c.Assert(len(hashed), gc.Equals, 24) // check we're not adding base64 padding. c.Assert(hashed, gc.Matches, base64Chars) } }
func (s *UserSuite) TestSetPasswordHash(c *gc.C) { user := s.Factory.MakeUser(c, nil) err := user.SetPasswordHash(utils.UserPasswordHash("foo", utils.CompatSalt), utils.CompatSalt) c.Assert(err, jc.ErrorIsNil) c.Assert(user.PasswordValid("foo"), jc.IsTrue) c.Assert(user.PasswordValid("bar"), jc.IsFalse) // User passwords should *not* use the fast PasswordHash function hash := utils.AgentPasswordHash("foo-12345678901234567890") c.Assert(err, jc.ErrorIsNil) err = user.SetPasswordHash(hash, "") c.Assert(err, jc.ErrorIsNil) c.Assert(user.PasswordValid("foo-12345678901234567890"), jc.IsFalse) }
// PasswordValid returns whether the given password is valid // for the given machine. func (m *Machine) PasswordValid(password string) bool { agentHash := utils.AgentPasswordHash(password) if agentHash == m.doc.PasswordHash { return true } // In Juju 1.16 and older we used the slower password hash for unit // agents. So check to see if the supplied password matches the old // path, and if so, update it to the new mechanism. // We ignore any error in setting the password, as we'll just try again // next time if utils.UserPasswordHash(password, utils.CompatSalt) == m.doc.PasswordHash { logger.Debugf("%s logged in with old password hash, changing to AgentPasswordHash", m.Tag()) m.setPasswordHash(agentHash) return true } return false }
// SetPassword sets the password for the machine's agent. func (m *Machine) SetPassword(password string) error { if len(password) < utils.MinAgentPasswordLength { return fmt.Errorf("password is only %d bytes long, and is not a valid Agent password", len(password)) } return m.setPasswordHash(utils.AgentPasswordHash(password)) }