1#!/usr/bin/perl 2 3use 5.006001; 4use strict; 5 6use File::Basename qw(basename); 7use Getopt::Long qw(GetOptions); 8use String::MkPasswd qw(mkpasswd); 9use Text::Wrap qw(wrap); 10 11# Defaults. 12use constant LENGTH => 9; 13use constant MINNUM => 2; 14use constant MINLOWER => 2; 15use constant MINUPPER => 2; 16use constant MINSPECIAL => 1; 17use constant DISTRIBUTE => ""; 18#use constant VERBOSE => ""; 19#use constant PASSWD => "/bin/passwd"; 20 21# Configuration. 22my $length = LENGTH; 23my $minnum = MINNUM; 24my $minlower = MINLOWER; 25my $minupper = MINUPPER; 26my $minspecial = MINSPECIAL; 27my $distribute = DISTRIBUTE; 28#my $verbose = VERBOSE; 29#my $passwd = PASSWD; 30my $help = ""; 31 32Getopt::Long::Configure("bundling"); 33my $getopt = GetOptions( 34 "length|l=i" => \$length, 35 "digits|d=i" => \$minnum, 36 "lower|c=i" => \$minlower, 37 "upper|C=i" => \$minupper, 38 "special|s=i" => \$minspecial, 39 "distribute|2" => \$distribute, 40 #"verbose|v" => \$verbose, 41 #"passwd|p" => \$passwd, 42 "help|h" => \$help, 43 44 # Getopt::Long doesn't support combining '--no' with options that take 45 # arguments, so this is just my way of faking it. 46 "nodigits|no-digits" => sub { $minnum = 0 }, 47 "nolower|no-lower" => sub { $minlower = 0 }, 48 "noupper|no-upper" => sub { $minupper = 0 }, 49 "nospecial|no-special" => sub { $minspecial = 0 }, 50); 51 52if ( $help ) { 53 &usage(); 54 exit 0; 55} 56 57if ( !$getopt ) { 58 &usage(); 59 exit 1; 60} 61 62my $pass = mkpasswd( 63 -length => $length, 64 -minnum => $minnum, 65 -minlower => $minlower, 66 -minupper => $minupper, 67 -minspecial => $minspecial, 68 -distribute => $distribute, 69); 70 71if ( !$pass ) { 72 $Text::Wrap::columns = 72; 73 print STDERR wrap("", "", 74 "Impossible to generate $length-character password with $minnum " 75 . "numbers, $minlower lowercase letters, $minupper uppercase letters " 76 . "and $minspecial special characters.\n" 77 ); 78 exit 1; 79} 80 81print "$pass\n"; 82exit 0; 83 84sub usage { 85 print <<EOF; 86Usage: @{[ basename $0 ]} [-options] 87 -l # | --length=# length of password (default = @{[ LENGTH ]}) 88 -d # | --digits=# min # of digits (default = @{[ MINNUM ]}) 89 -c # | --lower=# min # of lowercase chars (default = @{[ MINLOWER ]}) 90 -C # | --upper=# min # of uppercase chars (default = @{[ MINUPPER ]}) 91 -s # | --special=# min # of special chars (default = @{[ MINSPECIAL ]}) 92 -2 | --distribute alternate hands 93 --nodigits alias for --digits=0 94 --nolower alias for --lower=0 95 --noupper alias for --upper=0 96 --nospecial alias for --special=0 97EOF 98} 99 100__END__ 101 102=head1 NAME 103 104mkpasswd.pl - example to generate new password with String::MkPasswd 105 106=head1 SYNOPSIS 107 108 mkpasswd.pl [-options] 109 110 #!/bin/sh 111 NEW_PASSWD=`mkpasswd.pl` 112 113=head1 DESCRIPTION 114 115This program generates a random password, allowing for some tuning of 116character distribution. The password is sent to standard output. 117 118=head2 OPTIONS 119 120=over 4 121 122=item -l # | --length=# 123 124The total length of the password. The default is 9. 125 126=item -d # | --digits=# 127 128The minimum number of digits that will appear in the final password. 129The default is 2. 130 131=item -c # | --lower=# 132 133The minimum number of lower-case characters that will appear in the 134final password. The default is 2. 135 136=item -C # | --upper=# 137 138The minimum number of upper-case characters that will appear in the 139final password. The default is 2. 140 141=item -s # | --special=# 142 143The minimum number of non-alphanumeric characters that will appear in 144the final password. The default is 1. 145 146=item -2 | --distribute 147 148If specified, password characters will be distributed between the left- 149and right-hand sides of the keyboard. This makes it more difficult for 150an onlooker to see the password as it is typed. 151 152=item --nodigits | --no-digits 153 154Alias for --digits=0. 155 156=item --nolower | --no-lower 157 158Alias for --lower=0. 159 160=item --noupper | --no-upper 161 162Alias for --upper=0. 163 164=item --nospecial | --no-special 165 166Alias for --special=0. 167 168=back 169 170=head1 BUGS 171 172=over 4 173 174=item * 175 176While not really a bug, the .pl extension has been added to avoid 177conflict with the program of the same name distributed with Expect. 178 179=back 180 181=head1 TODO 182 183=over 4 184 185=item * 186 187For completeness, add user password setting functionality as found in 188Expect's L<mkpasswd(1)> example. 189 190=back 191 192=head1 SEE ALSO 193 194L<http://expect.nist.gov/#examples>, 195L<mkpasswd(1)>, 196L<String::MkPasswd> 197 198=head1 AKNOWLEDGEMENTS 199 200Don Libes of the National Institute of Standards and Technology, who 201wrote the Expect example, L<mkpasswd(1)>. 202 203=head1 AUTHOR 204 205Chris Grau E<lt>cgrau@cpan.orgE<gt> 206 207=head1 COPYRIGHT AND LICENSE 208 209Copyright (C) 2003-2004 by Chris Grau 210 211This library is free software; you can redistribute it and/or modify it 212under the same terms as Perl itself, either Perl version 5.8.1 or, at 213your option, any later version of Perl 5 you may have available. 214 215=cut 216