exec expect
-- "$0" ${1+"$@"}
# mkpasswd - make a password, if username given, set it.
# Author: Don Libes, NIST
if {[file executable
/bin
/nispasswd
]} {
set defaultprog
/bin
/nispasswd
} elseif
{[file executable
/bin
/yppasswd
]} {
set defaultprog
/bin
/yppasswd
} elseif
{[file executable
/bin
/passwd
]} {
set defaultprog
/bin
/passwd
while {[llength
$argv]>0} {
set flag
[lindex
$argv 0]
set length
[lindex
$argv 1]
set argv
[lrange
$argv 2 end
]
set minnum
[lindex
$argv 1]
set argv
[lrange
$argv 2 end
]
set minlower
[lindex
$argv 1]
set argv
[lrange
$argv 2 end
]
set minupper
[lindex
$argv 1]
set argv
[lrange
$argv 2 end
]
set minspecial
[lindex
$argv 1]
set argv
[lrange
$argv 2 end
]
set argv
[lrange
$argv 1 end
]
set prog
[lindex
$argv 1]
set argv
[lrange
$argv 2 end
]
set argv
[lrange
$argv 1 end
]
set user
[lindex
$argv 0]
set argv
[lrange
$argv 1 end
]
puts
"usage: mkpasswd \[args] \[user]"
puts
" where arguments are:"
puts
" -l # (length of password, default = $length)"
puts
" -d # (min # of digits, default = $minnum)"
puts
" -c # (min # of lowercase chars, default = $minlower)"
puts
" -C # (min # of uppercase chars, default = $minupper)"
puts
" -s # (min # of special chars, default = $minspecial)"
puts
" -v (verbose, show passwd interaction)"
puts
" -p prog (program to set password, default = $defaultprog)"
if {$minnum + $minlower + $minupper + $minspecial > $length} {
puts
"impossible to generate $length-character password\
with $minnum numbers, $minlower lowercase letters,\
$minupper uppercase letters and\
$minspecial special characters."
# if there is any underspecification, use additional lowercase letters
set minlower
[expr {$length - ($minnum + $minupper + $minspecial)}]
set lpass
"" ;# password chars typed by left hand
set rpass
"" ;# password chars typed by right hand
# insert char into password at a random position, thereby spreading
# the different kinds of characters throughout the password
proc insert
{pvar char
} {
set p
[linsert
$p [rand
[expr {(1+[llength
$p])}]] $char]
# choose left or right starting hand
set initially_left
[set isleft
[rand
2]]
# given a size, distribute between left and right hands
# taking into account where we left off
proc psplit
{max lvar rvar
} {
upvar
$lvar left
$rvar right
set left
[expr $max-$right]
set isleft
[expr !($max%2)]
set right
[expr $max-$left]
set lkeys
{q w e r t a s d f g z x c v b
}
set rkeys
{y u i o p h j k l n m
}
set rspec
{^
& * ( ) - = _
+ [ ] "{" "}" \\ |
; : ' \" < > , . ? /}
set lkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
set rkeys {a b c d e f g h i j k l m n o p q r s t u v w x y z}
set lnums {0 1 2 3 4 5 6 7 8 9}
set rnums {0 1 2 3 4 5 6 7 8 9}
set lspec {! @ # \$ % ~ ^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ?
/}
set rspec
{! @
# \$ % ~ ^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /}
set lkeys_length
[llength
$lkeys]
set rkeys_length
[llength
$rkeys]
set lnums_length
[llength
$lnums]
set rnums_length
[llength
$rnums]
set lspec_length
[llength
$lspec]
set rspec_length
[llength
$rspec]
psplit
$minnum left right
for {set i
0} {$i<$left} {incr i
} {
insert lpass
[lindex
$lnums [rand
$lnums_length]]
for {set i
0} {$i<$right} {incr i
} {
insert rpass
[lindex
$rnums [rand
$rnums_length]]
psplit
$minlower left right
for {set i
0} {$i<$left} {incr i
} {
insert lpass
[lindex
$lkeys [rand
$lkeys_length]]
for {set i
0} {$i<$right} {incr i
} {
insert rpass
[lindex
$rkeys [rand
$rkeys_length]]
psplit
$minupper left right
for {set i
0} {$i<$left} {incr i
} {
insert lpass
[string toupper
[lindex
$lkeys [rand
$lkeys_length]]]
for {set i
0} {$i<$right} {incr i
} {
insert rpass
[string toupper
[lindex
$rkeys [rand
$rkeys_length]]]
psplit
$minspecial left right
for {set i
0} {$i<$left} {incr i
} {
insert lpass
[lindex
$lspec [rand
$lspec_length]]
for {set i
0} {$i<$right} {incr i
} {
insert rpass
[lindex
$rspec [rand
$rspec_length]]
foreach l
$lpass r
$rpass {
if {[info exists user
]} {
# some systems say "Password (again):"
# if user isn't watching, check status
puts
-nonewline "$expect_out(buffer)"
puts
-nonewline "password for $user is "