3
3
# Copyright 2018 Daniel Long Sockwell <[email protected] >.
4
4
# All rights reserved. This file is licensed under the GPLv3+.
5
5
# Please see COPYING for more information.
6
+ # Please see man pass-gen(1) for usage and configuration instructions
6
7
7
8
8
9
# Default settings (unless overridden by command-line options or .passgenrc)
9
10
WORDLIST=/usr/local/lib/pass-gen/wordlists/EFF_wordlist_total
10
- SIZE_OF_WORDLIST=" not set"
11
+ SIZE_OF_WORDLIST=" not set" # Not a user-set value; computed based on supplied list
11
12
CHARLIST=/usr/local/lib/pass-gen/character-lists/default_character_list
12
- SIZE_OF_CHARLIST=" not set"
13
+ SIZE_OF_CHARLIST=" not set" # Not a user-set value; computed based on supplied list
13
14
PADDING_LENGTH_BEFORE=0
14
15
PADDING_LENGTH_AFTER=3
15
16
NUMBER_OF_WORDS=6
16
- CAPITAL_COUNTER=" $(( $(od - An - N2 - i / dev/ urandom) % (2 ) )) " # randomly 1 or 2
17
+ CAPITAL_COUNTER=" $(( $(od -- address- radix= n -- read- bytes= 2 - i / dev/ urandom) \
18
+ % (3 ) )) "
19
+ # This generates a cryptographically lecture random number between 0
20
+ # and 2 inclusive.
21
+ #
22
+ # This uses /dev/urandom as its secure source of entropy. See
23
+ # https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
24
+ # The way dev/urandom works is by producing a random number. We use
25
+ # od ("octal dump", though we're not using the "octal" part) to output
26
+ # two bytes of that random number and then take the remainder when divided
27
+ # by three. This gets us a secure, random number that is 0-2 inclusive
17
28
CAPITALIZATION_MODE=" both"
18
29
CAPITALIZATION_OPTIONS_PER_WORD=3
19
30
DISPLAY_PASSWORD=false
@@ -27,12 +38,13 @@ if [ -f /home/$USER/.passgenrc ]; then
27
38
# # Find the `current_project` key, and get the quoted string value
28
39
if [ $( grep word-list $CONFIG_FILE ) ]; then
29
40
WORDLIST=$( grep word-list $CONFIG_FILE | cut --delimiter== --fields=2)
30
- WORDLIST=$( echo $WORDLIST | sed -e " s_~_/home/${USER} _" )
41
+ # `delimiter= ` sets the delimiter to <SPACE>
42
+ WORDLIST=$( echo $WORDLIST | sed --expression=" s_~_/home/${USER} _" )
31
43
fi
32
44
33
45
if [ $( grep character-list $CONFIG_FILE ) ]; then
34
46
CHARLIST=$( grep character-list $CONFIG_FILE | cut --delimiter== --fields=2)
35
- CHARLIST=$( echo $CHARLIST | sed -e " s_~_/home/${USER} _" )
47
+ CHARLIST=$( echo $CHARLIST | sed --expression= " s_~_/home/${USER} _" )
36
48
fi
37
49
38
50
if [ $( grep capital-mode $CONFIG_FILE ) ]; then
66
78
# # OPTION COMMANDS
67
79
# #
68
80
81
+ # We parse commands manually to avoid dependencies on getopt or similar
69
82
cmd_version () {
83
+ # Display the version information
70
84
>&2 cat << -_EOF
71
85
pass-gen v.0.5.1
72
86
Copyright (C) 2018 Daniel Long Sockwell, www.codesections.com
@@ -81,6 +95,7 @@ Written by Daniel Long Sockwell
81
95
82
96
83
97
cmd_help () {
98
+ # Display usage information
84
99
>&2 cat << -_EOF
85
100
Usage: pass-gen [OPTION]
86
101
@@ -104,23 +119,29 @@ Full documentation avalible in the pass-gen(1) man page.
104
119
exit 0
105
120
}
106
121
122
+
107
123
cmd_error () {
124
+ # Display error information
108
125
>&2 cat << -_EOF
109
126
pass-gen: unrecognized option '$1 '
110
127
Try 'pass-gen --help' for more information.
111
128
_EOF
112
129
exit 1
113
130
}
114
131
132
+
115
133
cmd_echo () {
134
+ # Display the password
116
135
DISPLAY_PASSWORD=true
117
136
case $1 in
118
137
' ' |* [!0-9]* ) NUMBER_TO_DISPLAY=1; return 1;;
119
138
* ) NUMBER_TO_DISPLAY=$1 ;;
120
139
esac
121
140
}
122
141
142
+
123
143
cmd_length () {
144
+ # Set the number of words in the generated password
124
145
case $1 in
125
146
' ' |* [!0-9]* ) >&2 cat << -_EOF
126
147
"$1 " is not a valid length.
@@ -131,7 +152,9 @@ cmd_length() {
131
152
esac
132
153
}
133
154
155
+
134
156
cmd_wordlist () {
157
+ # Set the wordlist to be used
135
158
if [ ! -f $1 ]; then
136
159
echo " Wordlist file could not be found. Does it exist?"
137
160
exit 1
@@ -143,7 +166,9 @@ cmd_wordlist() {
143
166
fi
144
167
}
145
168
169
+
146
170
cmd_charlist () {
171
+ # Set the character list to be used
147
172
if [ ! -f $1 ]; then
148
173
echo " Character-list file could not be found. Does it exist?"
149
174
exit 1
@@ -155,7 +180,9 @@ cmd_charlist() {
155
180
fi
156
181
}
157
182
183
+
158
184
cmd_padding_length_before () {
185
+ # Set how many numbers should be used as padding before the generated words
159
186
case $1 in
160
187
' ' |* [!0-9]* ) >&2 cat << -_EOF
161
188
"$1 " is not a valid amount of padding.
@@ -166,7 +193,9 @@ cmd_padding_length_before() {
166
193
esac
167
194
}
168
195
196
+
169
197
cmd_padding_length_after () {
198
+ # Set how many numbers should be used as padding after the generated words
170
199
case $1 in
171
200
' ' |* [!0-9]* ) >&2 cat << -_EOF
172
201
"$1 " is not a valid amount of padding.
@@ -177,7 +206,9 @@ cmd_padding_length_after() {
177
206
esac
178
207
}
179
208
209
+
180
210
cmd_capital_mode () {
211
+ # Set the capitalization mode
181
212
case $1 in
182
213
all|initial|both) CAPITALIZATION_MODE=$1 ;;
183
214
* ) >&2 cat << -_EOF
@@ -191,12 +222,14 @@ cmd_capital_mode() {
191
222
fi
192
223
}
193
224
225
+
194
226
cmd_report_entrophy () {
195
227
REPORT_ENTROPY=true
196
228
}
197
229
198
- # Pick a random symbol from CHARLIST
230
+
199
231
generate_random_symbol () {
232
+ # Pick a random symbol from CHARLIST
200
233
MIN=1
201
234
SIZE_OF_CHARLIST=$( cat $CHARLIST | wc -l)
202
235
# Generate a random number between MAX and MIN
@@ -205,32 +238,34 @@ generate_random_symbol() {
205
238
}
206
239
207
240
208
- # Generate a random word from WORDLIST
209
241
generate_random_word () {
242
+ # Generate a random word from WORDLIST
210
243
MIN=1
211
244
SIZE_OF_WORDLIST=$( cat $WORDLIST | wc -l)
212
245
# Generate a random number between MAX and MIN
213
- RANDOM_NUM=" $(( $MIN + $(od - An - N 2 - i / dev/ urandom) % ($SIZE_OF_WORDLIST - $MIN + 1 ) )) "
246
+ RANDOM_NUM=" $(( $MIN + $(od -- address - radix = n -- read - bytes = 2 - i / dev/ urandom) % ($SIZE_OF_WORDLIST - $MIN + 1 ) )) "
214
247
215
248
RANDOM_WORD=" $( sed -n ${RANDOM_NUM} p $WORDLIST ) "
216
249
}
217
250
218
251
219
- # Capitalize the word if necessary
220
252
capitalize_all () {
253
+ # Capitalize the word if necessary
221
254
if [ $(( ($CAPITAL_COUNTER - 1 ) % 2 )) -eq " 0" ]; then
222
255
RANDOM_WORD=" $( echo $RANDOM_WORD | tr ' [:lower:]' ' [:upper:]' ) "
223
256
fi
224
257
CAPITAL_COUNTER=$(( $CAPITAL_COUNTER + 1 ))
225
258
}
226
259
260
+
227
261
capitalize_initial () {
228
262
if [ $(( $CAPITAL_COUNTER % 2 )) -eq " 0" ]; then
229
263
RANDOM_WORD=" $( echo $RANDOM_WORD | sed ' s/./\U&/' ) "
230
264
fi
231
265
CAPITAL_COUNTER=$(( $CAPITAL_COUNTER + 1 ))
232
266
}
233
267
268
+
234
269
capitalize_both () {
235
270
if [ $(( ($CAPITAL_COUNTER - 1 ) % 3 )) -eq " 0" ]; then
236
271
RANDOM_WORD=" $( echo $RANDOM_WORD | tr ' [:lower:]' ' [:upper:]' ) "
@@ -242,8 +277,8 @@ capitalize_both() {
242
277
}
243
278
244
279
245
- # Generate random numbers to pad the passphrase
246
280
generate_padding () {
281
+ # Generate random numbers to pad the passphrase
247
282
for i in $( seq 1 $PADDING_LENGTH_AFTER ) ; do
248
283
RANDOM_NUM=" $(( 0 + $(od - An - N2 - i / dev/ urandom) % (9 - 0 + 1 ) )) "
249
284
PADDING_AFTER=${PADDING_AFTER}${RANDOM_NUM}
@@ -254,8 +289,9 @@ generate_padding() {
254
289
done
255
290
}
256
291
257
- # Generate passphrase by combining random words with the chosen character
292
+
258
293
generate_passphrase () {
294
+ # Generate passphrase by combining random words with the chosen character
259
295
generate_random_symbol
260
296
for i in $( seq 1 $NUMBER_OF_WORDS ) ; do
261
297
generate_random_word
@@ -278,13 +314,15 @@ generate_passphrase() {
278
314
}
279
315
280
316
clear_passphrase () {
317
+ # Clears the passphrase from memory. Likely over-cautious, but intended
318
+ # as an extra security measure against out-of-process access
281
319
RANDOM_PASS=" "
282
320
PADDING_BEFORE=" "
283
321
PADDING_AFTER=" "
284
322
}
285
323
286
324
287
- # Process command-line options and update settings as required
325
+ # Process command-line options and update settings as required
288
326
if [[ " $1 " ]]; then
289
327
while [[ " $1 " ]]; do
290
328
currentParamater=$1
@@ -347,6 +385,8 @@ by the EFF Dice password tool contain 77 bits of entropy
347
385
_EOF
348
386
fi
349
387
388
+ # As a final, paranoid security practice, overwrite the generated passwords
389
+ # (again, to prevent out-of-process access)
350
390
RANDOM_PASS=" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
351
391
WORDLIST=" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
352
392
CHARLIST=" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
0 commit comments