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.
Files changed (4) hide show
  1. data/bin/passmakr +3 -0
  2. data/lib/passmakr.rb +46 -43
  3. data/passmakr.gemspec +2 -2
  4. 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
- else
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
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "passmakr"
3
- s.version = "1.0.0"
4
-
3
+ s.version = "1.1.0"
4
+
5
5
  s.authors = ["R.I.Pienaar"]
6
6
  s.date = %q{2009-10-11}
7
7
  s.default_executable = "passmakr"
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
- - 0
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.6
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