Class: HTAuth::Algorithm
- Inherits:
-
Object
- Object
- HTAuth::Algorithm
- Defined in:
- lib/htauth/algorithm.rb
Overview
Internal: Base class all the password algorithms derive from
Constant Summary collapse
- SALT_CHARS =
(%w[ . / ] + ("0".."9").to_a + ('A'..'Z').to_a + ('a'..'z').to_a).freeze
- MD5 =
Public: flag for the md5 algorithm
"md5".freeze
- SHA1 =
Public: flag for the sha1 algorithm
"sha1".freeze
- PLAINTEXT =
Public: flag for the plaintext algorithm
"plaintext".freeze
- CRYPT =
Public: flag for the crypt algorithm
"crypt".freeze
- DEFAULT =
Public: flag for the default algorithm
MD5
- EXISTING =
Public: flag to indicate using the existing algorithm of the entry
"existing".freeze
Class Method Summary collapse
- .algorithm_from_name(a_name, params = {}) ⇒ Object
- .algorithms_from_field(password_field) ⇒ Object
- .inherited(sub_klass) ⇒ Object
-
.secure_compare(a, b) ⇒ Object
Internal: Constant time string comparison.
- .sub_klasses ⇒ Object
Instance Method Summary collapse
-
#encode(password) ⇒ Object
Internal.
-
#gen_salt ⇒ Object
Internal: 8 bytes of random items from SALT_CHARS.
-
#prefix ⇒ Object
Internal.
-
#to_64(number, rounds) ⇒ Object
Internal: this is not the Base64 encoding, this is the to64() method from the apache protable runtime library.
Class Method Details
.algorithm_from_name(a_name, params = {}) ⇒ Object
29 30 31 32 |
# File 'lib/htauth/algorithm.rb', line 29 def algorithm_from_name(a_name, params = {}) raise InvalidAlgorithmError, "`#{a_name}' is an invalid encryption algorithm, use one of #{sub_klasses.keys.join(', ')}" unless sub_klasses[a_name.downcase] sub_klasses[a_name.downcase].new(params) end |
.algorithms_from_field(password_field) ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/htauth/algorithm.rb', line 34 def algorithms_from_field(password_field) matches = [] if password_field.index(sub_klasses[SHA1].new.prefix) then matches << sub_klasses[SHA1].new elsif password_field.index(sub_klasses[MD5].new.prefix) then p = password_field.split("$") matches << sub_klasses[MD5].new( :salt => p[2] ) else matches << sub_klasses[PLAINTEXT].new matches << sub_klasses[CRYPT].new( :salt => password_field[0,2] ) end return matches end |
.inherited(sub_klass) ⇒ Object
50 51 52 53 |
# File 'lib/htauth/algorithm.rb', line 50 def inherited(sub_klass) k = sub_klass.name.split("::").last.downcase sub_klasses[k] = sub_klass end |
.secure_compare(a, b) ⇒ Object
Internal: Constant time string comparison.
From github.com/rack/rack/blob/master/lib/rack/utils.rb
NOTE: the values compared should be of fixed length, such as strings that have already been processed by HMAC. This should not be used on variable length plaintext strings because it could leak length info via timing attacks.
67 68 69 70 71 72 73 74 75 |
# File 'lib/htauth/algorithm.rb', line 67 def secure_compare(a, b) return false unless a.bytesize == b.bytesize l = a.unpack("C*") r, i = 0, -1 b.each_byte { |v| r |= v ^ l[i+=1] } r == 0 end |
.sub_klasses ⇒ Object
55 56 57 |
# File 'lib/htauth/algorithm.rb', line 55 def sub_klasses @sub_klasses ||= {} end |
Instance Method Details
#encode(password) ⇒ Object
Internal
82 |
# File 'lib/htauth/algorithm.rb', line 82 def encode(password) ; end |
#gen_salt ⇒ Object
Internal: 8 bytes of random items from SALT_CHARS
85 86 87 88 89 |
# File 'lib/htauth/algorithm.rb', line 85 def gen_salt chars = [] 8.times { chars << SALT_CHARS[SecureRandom.random_number(SALT_CHARS.size)] } chars.join('') end |
#prefix ⇒ Object
Internal
79 |
# File 'lib/htauth/algorithm.rb', line 79 def prefix ; end |
#to_64(number, rounds) ⇒ Object
Internal: this is not the Base64 encoding, this is the to64() method from the apache protable runtime library
93 94 95 96 97 98 99 100 |
# File 'lib/htauth/algorithm.rb', line 93 def to_64(number, rounds) r = StringIO.new rounds.times do |x| r.print(SALT_CHARS[number % 64]) number >>= 6 end return r.string end |