passmakr 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/passmakr +3 -0
- data/lib/passmakr.rb +46 -43
- data/passmakr.gemspec +2 -2
- metadata +8 -3
data/bin/passmakr
CHANGED
@@ -45,6 +45,7 @@ opts = GetoptLong.new(
|
|
45
45
|
[ '--phonemic', '-p', GetoptLong::NO_ARGUMENT],
|
46
46
|
[ '--random', '-r', GetoptLong::NO_ARGUMENT],
|
47
47
|
[ '--urandom', '-u', GetoptLong::NO_ARGUMENT],
|
48
|
+
[ '--password', '-P', GetoptLong::REQUIRED_ARGUMENT],
|
48
49
|
[ '--help', '-h', GetoptLong::NO_ARGUMENT]
|
49
50
|
)
|
50
51
|
|
@@ -59,6 +60,8 @@ opts.each do |opt, arg|
|
|
59
60
|
mode = :random
|
60
61
|
when '--urandom'
|
61
62
|
mode = :urandom
|
63
|
+
when '--password'
|
64
|
+
mode = arg
|
62
65
|
when '--help'
|
63
66
|
begin
|
64
67
|
require 'rdoc/ri/ri_paths'
|
data/lib/passmakr.rb
CHANGED
@@ -90,6 +90,7 @@ class Passmakr
|
|
90
90
|
# * :phonemic - produces easily remembered passwords
|
91
91
|
# * :random - uses the ruby random function to generate a password
|
92
92
|
# * :urandom - uses linux /dev/urandom to generate a password
|
93
|
+
# * anything else will be used as the password instead of generating one
|
93
94
|
#
|
94
95
|
# Each instance will have a unique hash of password information
|
95
96
|
# in the password attribute, the hash will have members:
|
@@ -107,8 +108,10 @@ class Passmakr
|
|
107
108
|
pw = urandom(length)
|
108
109
|
when :random
|
109
110
|
pw = random(length)
|
110
|
-
|
111
|
+
when :phonemic
|
111
112
|
pw = phonemic(length)
|
113
|
+
else
|
114
|
+
pw = mode
|
112
115
|
end
|
113
116
|
|
114
117
|
preppw(pw)
|
@@ -119,7 +122,7 @@ class Passmakr
|
|
119
122
|
def get_vowel_or_consonant
|
120
123
|
rand( 2 ) == 1 ? VOWEL : CONSONANT
|
121
124
|
end
|
122
|
-
|
125
|
+
|
123
126
|
# Generate a memorable password of _length_ characters, using phonemes that
|
124
127
|
# a human-being can easily remember. _flags_ is one or more of
|
125
128
|
# <em>Passmakr::ONE_DIGIT</em> and <em>Passmakr::ONE_CASE</em>, logically
|
@@ -137,80 +140,80 @@ class Passmakr
|
|
137
140
|
# Generated passwords may contain any of the characters in
|
138
141
|
# <em>Passmakr::PASSWD_CHARS</em>.
|
139
142
|
def phonemic(length=8, flags=Passmakr::ONE_CASE)
|
140
|
-
|
143
|
+
|
141
144
|
pw = nil
|
142
145
|
ph_flags = flags
|
143
|
-
|
146
|
+
|
144
147
|
loop do
|
145
|
-
|
148
|
+
|
146
149
|
pw = ""
|
147
|
-
|
150
|
+
|
148
151
|
# Separate the flags integer into an array of individual flags
|
149
152
|
feature_flags = [ flags & ONE_DIGIT, flags & ONE_CASE ]
|
150
|
-
|
153
|
+
|
151
154
|
prev = []
|
152
155
|
first = true
|
153
156
|
desired = get_vowel_or_consonant
|
154
|
-
|
157
|
+
|
155
158
|
# Get an Array of all of the phonemes
|
156
159
|
phonemes = PHONEMES.keys.map { |ph| ph.to_s }
|
157
160
|
nr_phonemes = phonemes.size
|
158
|
-
|
161
|
+
|
159
162
|
while pw.length < length do
|
160
|
-
|
163
|
+
|
161
164
|
# Get a random phoneme and its length
|
162
165
|
phoneme = phonemes[ rand( nr_phonemes ) ]
|
163
166
|
ph_len = phoneme.length
|
164
|
-
|
167
|
+
|
165
168
|
# Get its flags as an Array
|
166
169
|
ph_flags = PHONEMES[ phoneme.to_sym ]
|
167
170
|
ph_flags = [ ph_flags & CONSONANT, ph_flags & VOWEL,
|
168
171
|
ph_flags & DIPHTHONG, ph_flags & NOT_FIRST ]
|
169
|
-
|
172
|
+
|
170
173
|
# Filter on the basic type of the next phoneme
|
171
174
|
next if ph_flags.include? desired
|
172
|
-
|
175
|
+
|
173
176
|
# Handle the NOT_FIRST flag
|
174
177
|
next if first and ph_flags.include? NOT_FIRST
|
175
|
-
|
178
|
+
|
176
179
|
# Don't allow a VOWEL followed a vowel/diphthong pair
|
177
180
|
next if prev.include? VOWEL and ph_flags.include? VOWEL and
|
178
181
|
ph_flags.include? DIPHTHONG
|
179
|
-
|
182
|
+
|
180
183
|
# Don't allow us to go longer than the desired length
|
181
184
|
next if ph_len > length - pw.length
|
182
|
-
|
185
|
+
|
183
186
|
# We've found a phoneme that meets our criteria
|
184
187
|
pw << phoneme
|
185
|
-
|
188
|
+
|
186
189
|
# Handle ONE_CASE
|
187
190
|
if feature_flags.include? ONE_CASE
|
188
|
-
|
191
|
+
|
189
192
|
if (first or ph_flags.include? CONSONANT) and rand( 10 ) < 3
|
190
193
|
pw[-ph_len, 1] = pw[-ph_len, 1].upcase
|
191
194
|
feature_flags.delete ONE_CASE
|
192
195
|
end
|
193
|
-
|
196
|
+
|
194
197
|
end
|
195
|
-
|
198
|
+
|
196
199
|
# Is password already long enough?
|
197
200
|
break if pw.length >= length
|
198
|
-
|
201
|
+
|
199
202
|
# Handle ONE_DIGIT
|
200
203
|
if feature_flags.include? ONE_DIGIT
|
201
|
-
|
204
|
+
|
202
205
|
if ! first and rand( 10 ) < 3
|
203
206
|
pw << ( rand( 10 ) + ?0 ).chr
|
204
207
|
feature_flags.delete ONE_DIGIT
|
205
|
-
|
208
|
+
|
206
209
|
first = true
|
207
210
|
prev = []
|
208
211
|
desired = get_vowel_or_consonant
|
209
212
|
next
|
210
213
|
end
|
211
|
-
|
214
|
+
|
212
215
|
end
|
213
|
-
|
216
|
+
|
214
217
|
if desired == CONSONANT
|
215
218
|
desired = VOWEL
|
216
219
|
elsif prev.include? VOWEL or ph_flags.include? DIPHTHONG or
|
@@ -219,20 +222,20 @@ class Passmakr
|
|
219
222
|
else
|
220
223
|
desired = VOWEL
|
221
224
|
end
|
222
|
-
|
225
|
+
|
223
226
|
prev = ph_flags
|
224
227
|
first = false
|
225
228
|
end
|
226
|
-
|
229
|
+
|
227
230
|
# Try again
|
228
231
|
break unless feature_flags.include? ONE_CASE or feature_flags.include? ONE_DIGIT
|
229
|
-
|
232
|
+
|
230
233
|
end
|
231
|
-
|
234
|
+
|
232
235
|
pw
|
233
236
|
end
|
234
|
-
|
235
|
-
|
237
|
+
|
238
|
+
|
236
239
|
# Generate a random password of _length_ characters. Unlike the
|
237
240
|
# Passmakr.phonemic method, no attempt will be made to generate a memorable
|
238
241
|
# password. Generated passwords may contain any of the characters in
|
@@ -240,15 +243,15 @@ class Passmakr
|
|
240
243
|
def random(length=8)
|
241
244
|
pw = ""
|
242
245
|
nr_chars = PASSWD_CHARS.size
|
243
|
-
|
246
|
+
|
244
247
|
srand()
|
245
248
|
|
246
249
|
length.times { pw << PASSWD_CHARS[ rand( nr_chars ) ] }
|
247
|
-
|
250
|
+
|
248
251
|
pw
|
249
252
|
end
|
250
|
-
|
251
|
-
|
253
|
+
|
254
|
+
|
252
255
|
# An alternative to Passmakr.random. It uses the <tt>/dev/urandom</tt>
|
253
256
|
# device to generate passwords, returning +nil+ on systems that do not
|
254
257
|
# implement the device. The passwords it generates may contain any of the
|
@@ -256,10 +259,10 @@ class Passmakr
|
|
256
259
|
# characters + and /.
|
257
260
|
def urandom(length=8)
|
258
261
|
return nil unless File.chardev? '/dev/urandom'
|
259
|
-
|
262
|
+
|
260
263
|
rand_data = nil
|
261
264
|
File.open( "/dev/urandom" ) { |f| rand_data = f.read( length ) }
|
262
|
-
|
265
|
+
|
263
266
|
# Base64 encode it
|
264
267
|
pw = [ rand_data ].pack( 'm' )[ 0 .. length - 1 ]
|
265
268
|
end
|
@@ -269,24 +272,24 @@ class Passmakr
|
|
269
272
|
# <em>Passmakr::SALT_CHARS</em>. If no salt is given, a randomly generated
|
270
273
|
# salt will be used.
|
271
274
|
def crypt(pw, type=DES, salt='')
|
272
|
-
|
275
|
+
|
273
276
|
unless ( salt.split( // ) - SALT_CHARS.split( // ) ).empty?
|
274
277
|
raise CryptError, 'bad salt'
|
275
278
|
end
|
276
|
-
|
279
|
+
|
277
280
|
salt = random( type ? 2 : 8 ) if salt.empty?
|
278
|
-
|
281
|
+
|
279
282
|
# (Linux glibc2 interprets a salt prefix of '$1$' as a call to use MD5
|
280
283
|
# instead of DES when calling crypt(3))
|
281
284
|
salt = '$1$' + salt if type == MD5
|
282
|
-
|
285
|
+
|
283
286
|
crypt = pw.crypt(salt)
|
284
|
-
|
287
|
+
|
285
288
|
# Raise an exception if MD5 was wanted, but result is not recognisable
|
286
289
|
if type == MD5 && crypt !~ /^\$1\$/
|
287
290
|
raise CryptError, 'MD5 not implemented'
|
288
291
|
end
|
289
|
-
|
292
|
+
|
290
293
|
crypt
|
291
294
|
end
|
292
295
|
|
data/passmakr.gemspec
CHANGED
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passmakr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 1
|
8
|
+
- 1
|
7
9
|
- 0
|
8
|
-
|
9
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- R.I.Pienaar
|
@@ -42,23 +43,27 @@ rdoc_options: []
|
|
42
43
|
require_paths:
|
43
44
|
- lib
|
44
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
none: false
|
45
47
|
requirements:
|
46
48
|
- - ">="
|
47
49
|
- !ruby/object:Gem::Version
|
50
|
+
hash: 3
|
48
51
|
segments:
|
49
52
|
- 0
|
50
53
|
version: "0"
|
51
54
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
52
56
|
requirements:
|
53
57
|
- - ">="
|
54
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
55
60
|
segments:
|
56
61
|
- 0
|
57
62
|
version: "0"
|
58
63
|
requirements: []
|
59
64
|
|
60
65
|
rubyforge_project:
|
61
|
-
rubygems_version: 1.3.
|
66
|
+
rubygems_version: 1.3.7
|
62
67
|
signing_key:
|
63
68
|
specification_version: 3
|
64
69
|
summary: Creates various types of passwords and shows them in often used formats
|