2021-06-01 12:20:20 +00:00
|
|
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
2017-01-27 08:17:03 +00:00
|
|
|
|
|
|
|
module PasswordHash
|
|
|
|
include ApplicationLib
|
|
|
|
|
2019-01-01 16:54:13 +00:00
|
|
|
extend self
|
2017-01-27 08:17:03 +00:00
|
|
|
|
|
|
|
def crypt(password)
|
2019-06-27 11:51:29 +00:00
|
|
|
# take a fresh Argon2::Password instances to ensure randomized salt
|
|
|
|
Argon2::Password.new(secret: secret).create(password)
|
2017-01-27 08:17:03 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def verified?(pw_hash, password)
|
|
|
|
Argon2::Password.verify_password(password, pw_hash, secret)
|
|
|
|
rescue
|
|
|
|
false
|
|
|
|
end
|
|
|
|
|
|
|
|
def crypted?(pw_hash)
|
2017-05-08 10:04:54 +00:00
|
|
|
return false if !pw_hash
|
|
|
|
return true if hashed_argon2?(pw_hash)
|
|
|
|
return true if hashed_sha2?(pw_hash)
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2017-05-08 10:04:54 +00:00
|
|
|
false
|
2017-01-27 08:17:03 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def legacy?(pw_hash, password)
|
2017-05-08 10:04:54 +00:00
|
|
|
return false if pw_hash.blank?
|
|
|
|
return false if !password
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2019-06-27 11:51:29 +00:00
|
|
|
return true if sha2?(pw_hash, password)
|
|
|
|
return true if hashed_argon2i?(pw_hash, password)
|
|
|
|
|
|
|
|
false
|
2017-01-27 08:17:03 +00:00
|
|
|
end
|
|
|
|
|
2017-05-08 10:04:54 +00:00
|
|
|
def hashed_sha2?(pw_hash)
|
|
|
|
pw_hash.start_with?('{sha2}')
|
|
|
|
end
|
2017-01-27 08:17:03 +00:00
|
|
|
|
2017-05-08 10:04:54 +00:00
|
|
|
def hashed_argon2?(pw_hash)
|
2019-06-27 11:51:29 +00:00
|
|
|
Argon2::Password.valid_hash?(pw_hash)
|
|
|
|
end
|
|
|
|
|
|
|
|
def hashed_argon2i?(pw_hash, password)
|
2017-05-08 10:04:54 +00:00
|
|
|
# taken from: https://github.com/technion/ruby-argon2/blob/7e1f4a2634316e370ab84150e4f5fd91d9263713/lib/argon2.rb#L33
|
2021-05-12 11:37:44 +00:00
|
|
|
return false if !pw_hash.match?(%r{^\$argon2i\$.{,112}})
|
2019-06-27 11:51:29 +00:00
|
|
|
|
|
|
|
# Argon2::Password.verify_password verifies argon2i hashes, too
|
|
|
|
verified?(pw_hash, password)
|
2017-05-08 10:04:54 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def sha2(password)
|
2017-01-27 08:17:03 +00:00
|
|
|
crypted = Digest::SHA2.hexdigest(password)
|
2017-05-08 10:04:54 +00:00
|
|
|
"{sha2}#{crypted}"
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def sha2?(pw_hash, password)
|
|
|
|
return false if !hashed_sha2?(pw_hash)
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2017-05-08 10:04:54 +00:00
|
|
|
pw_hash == sha2(password)
|
2017-01-27 08:17:03 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def secret
|
2018-09-28 12:14:46 +00:00
|
|
|
@secret ||= Setting.get('application_secret')
|
2017-01-27 08:17:03 +00:00
|
|
|
end
|
|
|
|
end
|