passmakr 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|