11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/puppet/functions/openldap_password.rb', line 11
Puppet::Functions.create_function(:openldap_password) do
dispatch :generate_password do
required_param 'String', :secret
optional_param 'Enum["PBKDF2","CRYPT","MD5","SMD5","SSHA","SHA"]', :scheme
optional_param 'Integer', :iterations
optional_param 'Enum["SHA256", "SHA512"]', :hash_type
return_type 'String'
end
def ab64_encode(data)
Base64.strict_encode64(data).tr('+', '.').delete('=')
end
def generate_password(secret, scheme = 'SSHA', iterations = 60_000, hash_type = 'SHA512')
case scheme[%r{([A-Z,0-9]+)}, 1]
when 'PBKDF2'
salt = OpenSSL::Random.random_bytes(16)
digest_map = {
'SHA256' => { name: 'SHA256', length: 32, obj: OpenSSL::Digest.new('SHA256') },
'SHA512' => { name: 'SHA512', length: 64, obj: OpenSSL::Digest.new('SHA512') },
}
config = digest_map[hash_type]
derived_key = OpenSSL::PKCS5.pbkdf2_hmac(
secret,
salt,
iterations,
config[:length],
config[:obj],
)
password = "{PBKDF2-#{config[:name]}}#{iterations}$#{ab64_encode(salt)}$#{ab64_encode(derived_key)}"
when 'CRYPT'
salt = call_function('fqdn_rand_string', 2)
password = "{CRYPT}#{secret.crypt(salt)}"
when 'MD5'
password = "{MD5}#{Digest::MD5.hexdigest(secret)}"
when 'SMD5'
salt = call_function('fqdn_rand_string', 8)
md5_hash_with_salt = "#{Digest::MD5.digest(secret + salt)}#{salt}"
password = "{SMD5}#{[md5_hash_with_salt].pack('m').delete("\n")}"
when 'SSHA'
salt = call_function('fqdn_rand_string', 8)
password = "{SSHA}#{Base64.encode64("#{Digest::SHA1.digest(secret + salt)}#{salt}").chomp}"
when 'SHA'
password = "{SHA}#{Digest::SHA1.hexdigest(secret)}"
else
raise(Puppet::ParseError, "openldap_password(): Unrecognized scheme #{scheme}")
end
password
end
end
|