Guest User

mkpasswd

a guest
Aug 6th, 2013
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 5.38 KB | None | 0 0
  1. #!/bin/sh
  2. # \
  3. exec expect -- "$0" ${1+"$@"}
  4. # mkpasswd - make a password, if username given, set it.
  5. # Author: Don Libes, NIST
  6.  
  7. # defaults
  8. set length 9
  9. set minnum 2
  10. set minlower 2
  11. set minupper 2
  12. set minspecial 1
  13. set verbose 0
  14. set distribute 0
  15.  
  16. if {[file executable /bin/nispasswd]} {
  17.     set defaultprog /bin/nispasswd
  18. } elseif {[file executable /bin/yppasswd]} {
  19.     set defaultprog /bin/yppasswd
  20. } elseif {[file executable /bin/passwd]} {
  21.     set defaultprog /bin/passwd
  22. } else {
  23.     set defaultprog passwd
  24. }
  25. set prog $defaultprog
  26.  
  27. while {[llength $argv]>0} {
  28.     set flag [lindex $argv 0]
  29.     switch -- $flag \
  30.     "-l" {
  31.         set length [lindex $argv 1]
  32.         set argv [lrange $argv 2 end]
  33.     } "-d" {
  34.         set minnum [lindex $argv 1]
  35.         set argv [lrange $argv 2 end]
  36.     } "-c" {
  37.         set minlower [lindex $argv 1]
  38.         set argv [lrange $argv 2 end]
  39.     } "-C" {
  40.         set minupper [lindex $argv 1]
  41.         set argv [lrange $argv 2 end]
  42.     } "-s" {
  43.         set minspecial [lindex $argv 1]
  44.         set argv [lrange $argv 2 end]
  45.     } "-v" {
  46.         set verbose 1
  47.         set argv [lrange $argv 1 end]
  48.     } "-p" {
  49.         set prog [lindex $argv 1]
  50.         set argv [lrange $argv 2 end]
  51.     } "-2" {
  52.         set distribute 1
  53.         set argv [lrange $argv 1 end]
  54.     } default {
  55.         set user [lindex $argv 0]
  56.         set argv [lrange $argv 1 end]
  57.         break
  58.     }
  59. }
  60.  
  61. if {[llength $argv]} {
  62.     puts "usage: mkpasswd \[args] \[user]"
  63.     puts "  where arguments are:"
  64.     puts "    -l #      (length of password, default = $length)"
  65.     puts "    -d #      (min # of digits, default = $minnum)"
  66.     puts "    -c #      (min # of lowercase chars, default = $minlower)"
  67.     puts "    -C #      (min # of uppercase chars, default = $minupper)"
  68.     puts "    -s #      (min # of special chars, default = $minspecial)"
  69.     puts "    -v        (verbose, show passwd interaction)"
  70.     puts "    -p prog   (program to set password, default = $defaultprog)"
  71.     exit 1
  72. }
  73.  
  74. if {$minnum + $minlower + $minupper + $minspecial > $length} {
  75.     puts "impossible to generate $length-character password\
  76.         with $minnum numbers, $minlower lowercase letters,\
  77.         $minupper uppercase letters and\
  78.         $minspecial special characters."
  79.     exit 1
  80. }
  81.  
  82. # if there is any underspecification, use additional lowercase letters
  83. set minlower [expr {$length - ($minnum + $minupper + $minspecial)}]
  84.  
  85. set lpass ""        ;# password chars typed by left hand
  86. set rpass ""        ;# password chars typed by right hand
  87.  
  88. # insert char into password at a random position, thereby spreading
  89. # the different kinds of characters throughout the password
  90. proc insert {pvar char} {
  91.     upvar $pvar p
  92.  
  93.     set p [linsert $p [rand [expr {(1+[llength $p])}]] $char]
  94. }
  95.  
  96. proc rand {m} {
  97.     expr {int($m*rand())}
  98. }
  99.  
  100. # choose left or right starting hand
  101. set initially_left [set isleft [rand 2]]
  102.  
  103. # given a size, distribute between left and right hands
  104. # taking into account where we left off
  105. proc psplit {max lvar rvar} {
  106.     upvar $lvar left $rvar right
  107.     global isleft
  108.  
  109.     if {$isleft} {
  110.         set right [expr $max/2]
  111.         set left [expr $max-$right]
  112.         set isleft [expr !($max%2)]
  113.     } else {
  114.         set left [expr $max/2]
  115.         set right [expr $max-$left]
  116.         set isleft [expr $max%2]
  117.     }
  118. }
  119.  
  120. if {$distribute} {
  121.     set lkeys {q w e r t a s d f g z x c v b}
  122.     set rkeys {y u i o p h j k l n m}
  123.     set lnums {1 2 3 4 5 6}
  124.     set rnums {7 8 9 0}
  125.     set lspec {! @ # \$ %}
  126.     set rspec {^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /}
  127. } else {
  128.     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}
  129.     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}
  130.     set lnums {0 1 2 3 4 5 6 7 8 9}
  131.     set rnums {0 1 2 3 4 5 6 7 8 9}
  132.     set lspec {! @ # \$ % ~ ^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /}
  133.     set rspec {! @ # \$ % ~ ^ & * ( ) - = _ + [ ] "{" "}" \\ | ; : ' \" < > , . ? /}
  134. }
  135.  
  136. set lkeys_length [llength $lkeys]
  137. set rkeys_length [llength $rkeys]
  138. set lnums_length [llength $lnums]
  139. set rnums_length [llength $rnums]
  140. set lspec_length [llength $lspec]
  141. set rspec_length [llength $rspec]
  142.  
  143. psplit $minnum left right
  144. for {set i 0} {$i<$left} {incr i} {
  145.     insert lpass [lindex $lnums [rand $lnums_length]]
  146. }
  147. for {set i 0} {$i<$right} {incr i} {
  148.     insert rpass [lindex $rnums [rand $rnums_length]]
  149. }
  150.  
  151. psplit $minlower left right
  152. for {set i 0} {$i<$left} {incr i} {
  153.     insert lpass [lindex $lkeys [rand $lkeys_length]]
  154. }
  155. for {set i 0} {$i<$right} {incr i} {
  156.     insert rpass [lindex $rkeys [rand $rkeys_length]]
  157. }
  158.  
  159. psplit $minupper left right
  160. for {set i 0} {$i<$left} {incr i} {
  161.     insert lpass [string toupper [lindex $lkeys [rand $lkeys_length]]]
  162. }
  163. for {set i 0} {$i<$right} {incr i} {
  164.     insert rpass [string toupper [lindex $rkeys [rand $rkeys_length]]]
  165. }
  166.  
  167. psplit $minspecial left right
  168. for {set i 0} {$i<$left} {incr i} {
  169.     insert lpass [lindex $lspec [rand $lspec_length]]
  170. }
  171. for {set i 0} {$i<$right} {incr i} {
  172.     insert rpass [lindex $rspec [rand $rspec_length]]
  173. }
  174.  
  175. # merge results together
  176. foreach l $lpass r $rpass {
  177.     if {$initially_left} {
  178.     append password $l $r
  179.     } else {
  180.     append password $r $l
  181.     }
  182. }
  183.  
  184. if {[info exists user]} {
  185.     if {!$verbose} {
  186.         log_user 0
  187.     }
  188.  
  189.     spawn $prog $user
  190.     expect {
  191.         "assword*:" {
  192.             # some systems say "Password (again):"
  193.             send "$password\r"
  194.             exp_continue
  195.         }
  196.     }
  197.  
  198.     # if user isn't watching, check status
  199.     if {!$verbose} {
  200.         if {[lindex [wait] 3]} {
  201.             puts -nonewline "$expect_out(buffer)"
  202.             exit 1
  203.         }
  204.     }
  205.  
  206.         if {$verbose} {
  207.         puts -nonewline "password for $user is "
  208.         }
  209. }
  210.  
  211. puts "$password"
Advertisement
Add Comment
Please, Sign In to add comment