This repository was archived by the owner on Nov 15, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuser_password.rb
92 lines (81 loc) · 2.63 KB
/
user_password.rb
1
2
3
4
5
6
7
8
9
10
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
84
85
86
87
88
89
90
91
92
require 'English'
require 'digest/md5'
require 'digest/sha1'
module ActiveLdap
module UserPassword
module_function
def valid?(password, hashed_password)
unless /^\{([A-Z][A-Z\d]+)\}/ =~ hashed_password
raise ArgumentError, _("Invalid hashed password: %s") % hashed_password
end
type = $1
hashed_password_without_type = $POSTMATCH
normalized_type = type.downcase
unless respond_to?(normalized_type)
raise ArgumentError, _("Unknown Hash type: %s") % type
end
salt_extractor = "extract_salt_for_#{normalized_type}"
if respond_to?(salt_extractor)
salt = send(salt_extractor, hashed_password_without_type)
if salt.nil?
raise ArgumentError,
_("Can't extract salt from hashed password: %s") % hashed_password
end
generated_password = send(normalized_type, password, salt)
else
generated_password = send(normalized_type, password)
end
hashed_password == generated_password
end
def crypt(password, salt=nil)
salt ||= "$1$#{Salt.generate(8)}"
"{CRYPT}#{password.crypt(salt)}"
end
def extract_salt_for_crypt(crypted_password)
if /^\$1\$/ =~ crypted_password
$MATCH + $POSTMATCH[0, 8].sub(/\$.*/, '') + "$"
else
crypted_password[0, 2]
end
end
def md5(password)
"{MD5}#{[Digest::MD5.digest(password)].pack('m').chomp}"
end
def smd5(password, salt=nil)
if salt and salt.size != 4
raise ArgumentError, _("salt size must be == 4: %s") % salt.inspect
end
salt ||= Salt.generate(4)
md5_hash_with_salt = "#{Digest::MD5.digest(password + salt)}#{salt}"
"{SMD5}#{[md5_hash_with_salt].pack('m').chomp}"
end
def extract_salt_for_smd5(smd5ed_password)
Base64.decode64(smd5ed_password)[-4, 4]
end
def sha(password)
"{SHA}#{[Digest::SHA1.digest(password)].pack('m').chomp}"
end
def ssha(password, salt=nil)
if salt and salt.size != 4
raise ArgumentError, _("salt size must be == 4: %s") % salt.inspect
end
salt ||= Salt.generate(4)
sha1_hash_with_salt = "#{Digest::SHA1.digest(password + salt)}#{salt}"
"{SSHA}#{[sha1_hash_with_salt].pack('m').chomp}"
end
def extract_salt_for_ssha(sshaed_password)
extract_salt_for_smd5(sshaed_password)
end
module Salt
CHARS = ['.', '/'] + ['0'..'9', 'A'..'Z', 'a'..'z'].collect do |x|
x.to_a
end.flatten
module_function
def generate(length)
salt = ""
length.times {salt << CHARS[rand(CHARS.length)]}
salt
end
end
end
end