Class: EasyPassword
- Inherits:
-
Object
- Object
- EasyPassword
- Defined in:
- lib/easy-password.rb,
lib/easy-password/version.rb
Overview
Adding a simple password generator and using it by default:
# Generate 10 random alphanumeric characters
EasyPassword.generator :random10 do
SecureRandom.alphanumeric(10)
end
# Define the default generator
EasyPassword.default_generator = :random10
Adding a checker
# Implementing classic at least 1 lowercase, 1 upercase, 1 digit
EasyPassword.checker :aA1 do |password, all|
list = { /\d/ => :digit_needed,
/[A-Z]/ => :upercase_needed,
/[a-z]/ => :lowercase_needed,
}.lazy.map {|regex, failure| failure if password !~ regex }
.reject(&:nil?)
all ? list.to_a : list.first
end
# Looking for known bad passwords in a database (using Sequel)
Password.checker :hack_dictionary do |password, all|
! DB[:bad_passwords].first(:password => password).nil?
end
Creating password
password = EasyPassword.new
password = EasyPassword.new('foobar')
Checking for weakness
password.weakness
Constant Summary collapse
- Digest =
OpenSSL::Digest
- VERSION =
Version
'0.1'
Class Method Summary collapse
-
.checker(name) {|password, all| ... } ⇒ Object
DSL to ass a new password checker.
-
.default_checkers ⇒ Object
List of default checkers to use.
-
.default_checkers=(checkers) ⇒ Object
Define the list of default checkers to use.
-
.default_generator ⇒ Object
Default generator.
-
.default_generator=(type) ⇒ Object
Define the default generator to use.
-
.generate(type = self.default_generator) ⇒ String
Generate a plain text password string.
-
.generator(name) {|| ... } ⇒ Object
DSL to add a new password generator.
-
.hide ⇒ Object
Is password value hidden when calling #to_s.
-
.hide=(hide) ⇒ Object
Control if password value is hidden when calling #to_s.
-
.lmhash(password) ⇒ String
Create a LMHASH-hashed password.
-
.md5(password) ⇒ String
Create a MD5-hashed password.
-
.ntlm(password) ⇒ String
Create an NTML-hashed password.
-
.sha(password) ⇒ String
Create a SHA-hashed password.
-
.sha256(password) ⇒ String
Create a SHA256-hashed password.
-
.weakness(password, *checkers, all: true) ⇒ Hash{Symbol=>Array<Symbol>}
Check for weakness.
Instance Method Summary collapse
-
#initialize(password = EasyPassword::generate) ⇒ EasyPassword
constructor
Create a new EasyPassword.
-
#lmhash ⇒ String
Get the LMHASH-hashed password.
-
#md5 ⇒ String
Get the MD5-hashed password.
-
#ntlm ⇒ String
Get the NTLM-hashed password.
-
#raw ⇒ String
Get the plain text password.
-
#sha ⇒ String
Get the SHA256-hashed password.
-
#sha256 ⇒ String
Get the SHA256-hashed password.
-
#to_s ⇒ String
Display password.
-
#weakness(*checkers, all: true) ⇒ Hash{Symbol=>Array<Symbol>}
Check for weakness.
Constructor Details
#initialize(password = EasyPassword::generate) ⇒ EasyPassword
Create a new EasyPassword
234 235 236 |
# File 'lib/easy-password.rb', line 234 def initialize(password = EasyPassword::generate) @passwd = password.clone.freeze end |
Class Method Details
.checker(name) {|password, all| ... } ⇒ Object
DSL to ass a new password checker
112 113 114 |
# File 'lib/easy-password.rb', line 112 def self.checker(name, &block) @checkers[name] ||= block end |
.default_checkers ⇒ Object
List of default checkers to use
90 91 92 |
# File 'lib/easy-password.rb', line 90 def self.default_checkers @default_checkers end |
.default_checkers=(checkers) ⇒ Object
Define the list of default checkers to use
84 85 86 |
# File 'lib/easy-password.rb', line 84 def self.default_checkers=(checkers) @default_checkers = checkers end |
.default_generator ⇒ Object
Default generator
74 75 76 |
# File 'lib/easy-password.rb', line 74 def self.default_generator @default_generator end |
.default_generator=(type) ⇒ Object
Define the default generator to use
68 69 70 |
# File 'lib/easy-password.rb', line 68 def self.default_generator=(type) @default_generator = type end |
.generate(type = self.default_generator) ⇒ String
Generate a plain text password string.
159 160 161 162 163 164 165 166 |
# File 'lib/easy-password.rb', line 159 def self.generate(type = self.default_generator) if type.nil? raise ArgumentError, 'invalid generator type' end @generators[type]&.call() || raise("requested generator '#{type}' doesn't exist") end |
.generator(name) {|| ... } ⇒ Object
DSL to add a new password generator
100 101 102 |
# File 'lib/easy-password.rb', line 100 def self.generator(name, &block) @generators[name] = block end |
.hide ⇒ Object
Is password value hidden when calling #to_s
53 54 55 |
# File 'lib/easy-password.rb', line 53 def self.hide @hide end |
.hide=(hide) ⇒ Object
Control if password value is hidden when calling #to_s
59 60 61 |
# File 'lib/easy-password.rb', line 59 def self.hide=(hide) @hide = hide end |
.lmhash(password) ⇒ String
Create a LMHASH-hashed password
219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/easy-password.rb', line 219 def self.lmhash(password) passwd = password[0..13].upcase passwd = passwd + "\000" * (14 - passwd.length) des = OpenSSL::Cipher::Cipher.new('des-ecb') des.encrypt [passwd[0..6], passwd[7..13]].collect { |key56| keybin = key56.unpack('B*')[0].scan(/.{7}/).collect {|k| k + (k.count('1') % 2 == 0 ? '1' : '0') } des.key = keybin.pack('B8' * 8) des.update('KGS!@#$%') }.join.unpack('C*').map { |b| '%02x' % b }.join end |
.md5(password) ⇒ String
Create a MD5-hashed password
175 176 177 |
# File 'lib/easy-password.rb', line 175 def self.md5(password) "{MD5}" + [Digest::MD5.digest(password) ].pack('m0') end |
.ntlm(password) ⇒ String
Create an NTML-hashed password
208 209 210 |
# File 'lib/easy-password.rb', line 208 def self.ntlm(password) Digest::MD4.hexdigest(password.encode("utf-16le")) end |
.sha(password) ⇒ String
Create a SHA-hashed password
186 187 188 |
# File 'lib/easy-password.rb', line 186 def self.sha(password) "{SHA}" + [Digest::SHA1.digest(password) ].pack('m0') end |
.sha256(password) ⇒ String
Create a SHA256-hashed password
197 198 199 |
# File 'lib/easy-password.rb', line 197 def self.sha256(password) "{sha256}" + [Digest::SHA256.digest(password)].pack('m0') end |
.weakness(password, *checkers, all: true) ⇒ Hash{Symbol=>Array<Symbol>}
Check for weakness
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/easy-password.rb', line 127 def self.weakness(password, *checkers, all: true) return nil if @checkers.empty? password = password.raw if password.kind_of?(EasyPassword) checkers = self.default_checkers if checkers.empty? list = if checkers.nil? || checkers.empty? then @checkers.lazy else checkers.lazy.map {|n| [n, @checkers.fetch(n)] } end list = list.map {|name, checker| case r = checker.call(password, all: all) when Array then [ name, r ] unless r.empty? when Symbol then [ name, [ r ] ] when true then [ name, [ name ] ] when nil, false else raise ArgumentError, 'unsupported checker return value' end }.reject(&:nil?) list = if all then Hash[list.to_a] else Hash[*list.first].transform_values {|v| v[0,1] } end list unless list.empty? end |
Instance Method Details
#lmhash ⇒ String
Get the LMHASH-hashed password
287 288 289 |
# File 'lib/easy-password.rb', line 287 def lmhash self.class.lmhash(@passwd) end |
#md5 ⇒ String
Get the MD5-hashed password
269 270 271 |
# File 'lib/easy-password.rb', line 269 def md5 self.class.md5(@passwd) end |
#ntlm ⇒ String
Get the NTLM-hashed password
278 279 280 |
# File 'lib/easy-password.rb', line 278 def ntlm self.class.ntlm(@passwd) end |
#raw ⇒ String
Get the plain text password
242 243 244 |
# File 'lib/easy-password.rb', line 242 def raw @passwd end |
#sha ⇒ String
Get the SHA256-hashed password
251 252 253 |
# File 'lib/easy-password.rb', line 251 def sha self.class.sha(@passwd) end |
#sha256 ⇒ String
Get the SHA256-hashed password
260 261 262 |
# File 'lib/easy-password.rb', line 260 def sha256 self.class.sha256(@passwd) end |
#to_s ⇒ String
Display password. The behavior is controlled by Password.hide, so either the plain text password will be displayed or ********
298 299 300 |
# File 'lib/easy-password.rb', line 298 def to_s self.class.hide != true ? "********" : self.raw end |
#weakness(*checkers, all: true) ⇒ Hash{Symbol=>Array<Symbol>}
Check for weakness
312 313 314 |
# File 'lib/easy-password.rb', line 312 def weakness(*checkers, all: true) self.class.weakness(@passwd, *checkers, all: all) end |