Generated: Tue Feb 2 17:54:40 2010 from genpass.pl 2008/04/02 7.4 KB.
#!/perl -w # NAME: genpass.pl # AIM: generate a STRONG random password # ========================================================================== # 02/04/2008 - change from using batch file to control repeats, to directly # getting the 'Y' from within Perl. This way AVOID # adding unaccepted passwords to the file, since the file is ONLY written # if 'Y' is entered ... # ========================================================================== # 12/07/2007 - add -s to show password list # 05/07/2007 - add LOG of passwords generated # 24/06/2007 - removed log file. # 20/06/2007 geoff mclane - http://goeffair.net use strict; use warnings; my @items = qw( 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 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 1 2 3 4 5 6 7 8 9 ); my $icnt = scalar @items; my $cntuc = 0; my $cntlc = 0; my $cntnm = 0; my $cyccnt = 0; my $pwlen = 9; my $finalpwd = ''; my $verb = 0; my $single = 1; # each item used ONLY once in each sequence my $firstval = 0; my $capfirst = 1; my @vals = (); my $passfile = 'C:\GTools\perl\genpass.txt'; my @passlines = (); my $usrname = ''; my $dry_run = 0; my $waitinp = 1; my $passcnt = 0; my @prevpasses = (); sub load_passes { if (open INF, "<$passfile") { @passlines = <INF>; close INF; } @prevpasses = (); foreach my $pss (@passlines) { chomp $pss; my @arr = split(',',$pss); if (length($arr[0])) { push(@prevpasses, $arr[0]); } } } sub is_in_previous { my ($cp) = shift; ###prt( "Checking [$cp] no tin previous ...\n" ); foreach my $ps (@prevpasses) { ###prt( "Comparing [$cp] with [$ps] ...\n" ); if ($cp eq $ps) { ###prt( "Found ...\n" ); return 1; } } ###prt( "$cp NOT FOUND ...\n" ); return 0; } sub write_pass_file { if (open OUTF, ">$passfile") { foreach my $pw (@passlines) { chomp $pw; if (length($pw)) { print OUTF "$pw\n"; } } close OUTF; } } sub give_help { prt( "genpass [Options] [User]\n" ); prt( "Options:\n" ); prt( " -? This brief help.\n" ); prt( " -c Disable CAPITAL first ...\n" ); # prt( " -d pwd Delete this entry.\n" ); prt( " -l N Number of charaters in password. Min. is 5. Default is $pwlen\n" ); prt( " -s Show current password list, if any ...\n" ); mydie( " -v Run in verbose mode.\n" ); } sub show_passes { my $max = scalar @passlines; my $msg = ''; if ($max) { prt( "List of $max passwords ...\n" ); for (my $i = 0; $i < $max; $i++) { my $ps = $passlines[$i]; chomp $ps; my @arr = split(',',$ps); my $len = scalar @arr; if ($len) { if ($len >= 2) { $msg = "pwd: ".$arr[0].",".$arr[1]; for (my $i = 2; $i < $len; $i++) { $msg .= ','.$arr[$i]; } prt( "$msg\n" ); } else { prt( "pwd: ".$arr[0].",<none>\n" ); } } } } else { prt( "Presently NO password list ...\n" ); } exit(2); } sub delete_pass { my ($pwd) = shift; my $max = scalar @passlines; if ($max) { prt( "List of $max passwords ...\n" ); for (my $i = 0; $i < $max; $i++) { my $ps = $passlines[$i]; my @arr = split(',',$ps); if ($arr[0] eq $pwd) { } } } else { prt( "Presently NO password list ...\n" ); } exit(3); } # Ensure argument exists, or die. sub require_arg { my ($arg, @arglist) = @_; mydie( "ERROR: no argument given for option '$arg' ...\n" ) if ! @arglist; } sub parse_args { my (@av) = @_; my $ic = 0; my $un = 0; while (@av) { my $arg = $av[0]; if ($arg =~ /^-{1}/) { if (($arg eq '-h')||($arg eq '-?')) { give_help(); # } elsif ($arg eq '-d') { # require_arg(@av); # shift @av; # $arg = $av[0]; # prt( "Delete password $arg ...\n" ); # delete_pass($arg); } elsif ($arg eq '-s') { show_passes(); } elsif ($arg eq '-v') { $verb = 1; prt( "Set verbose output ...\n" ); } elsif ($arg eq '-c') { $capfirst = 0; prt( "Disabled CAPS first ...\n" ); } elsif ($arg eq '-l') { require_arg(@av); shift @av; $pwlen = $av[0]; prt( "Set password length to $pwlen ...\n" ); } elsif ($arg eq '-dry-run') { $dry_run = 1; prt( "Set DRY RUN ONLY ...\n" ); } else { mydie( "ERROR: Option [$arg] UNKNOWN! Try -? for HELP ...\n" ); } } elsif (length($arg)) { $usrname .= ',' if length($usrname); $usrname .= $arg; $un = 1; } shift @av; $ic++; } if ($pwlen < 5) { mydie( "ERROR: Password can NOT be less than 5 characters\n" ); } prt( "Set username to $usrname ...\n" ) if ($un); } load_passes(); parse_args(@ARGV); ###prt( "52 value = ". $items[52] . "\n" ); prt( "From $icnt characters i. A-Z, ii. a-z, iii. 1-9 ... Note no ZERO!\n" ) if ($verb); prt( "Random password of length $pwlen ... with at least 1 from each group.\n" ) if ($verb); sub get_password { my $lastpwd = $finalpwd; while( ($cntuc == 0) || ($cntlc == 0) || ($cntnm == 0) || ($firstval >= 52) || ($cntnm > 2)) { $cyccnt++; $cntuc = 0; $cntlc = 0; $cntnm = 0; $firstval = 0; @vals = (); $finalpwd = get_r_pass(); if (is_in_previous($finalpwd)) { $cntuc = 0; } else { if ($single) { my @arr = split('',$finalpwd); my $max = scalar @arr; for (my $i = 0; $i < $max; $i++) { my $itm1 = $arr[$i]; for (my $j = 0; $j < $max; $j++) { if ($i != $j) { my $itm2 = $arr[$j]; if ($itm1 eq $itm2) { $cntuc = 0; $cntlc = 0; $cntnm = 0; last; } } } } } } } } sub get_r_pass { my $pw = ''; my $val = int(rand($icnt)); if ($capfirst) { while ($val >= 26) { $val = int(rand($icnt)); } } push(@vals, $val); $firstval = $val; my $itm = $items[$val]; $pw .= $itm; #prt( "$itm" ); if ($val < 26) { $cntuc++; } elsif ($val < 52) { $cntlc++; } else { $cntnm++; } for (my $i = 1; $i < $pwlen; $i++) { $val = int(rand($icnt)); push(@vals, $val); $itm = $items[$val]; $pw .= $itm; #prt( "$itm" ); if ($val < 26) { $cntuc++; } elsif ($val < 52) { $cntlc++; } else { $cntnm++; } } return $pw; } $cntuc = 0; get_password(); prt("With $cntuc Upper, $cntlc Lower, $cntnm Number [in $cyccnt cycles]\n") if ($verb); if ($dry_run) { prt("$finalpwd ($cyccnt) usr=[$usrname] DRY RUN ONLY!\n"); } else { $usrname = '<none given>' if (length($usrname) == 0); while ($waitinp) { prt("pwd=[ $finalpwd ] ($cyccnt) usr=[$usrname]\n" ); prt( "Enter Y to accept, Q to exit, U=User Name, else cycle : " ); my $inp = <STDIN>; chomp $inp; if (lc($inp) eq 'y') { push(@passlines, "$finalpwd,$usrname"); $passcnt = scalar @passlines; prt( "Adding [$finalpwd] for usr=[$usrname]\nto [$passfile] ... total $passcnt lines ...\n" ); write_pass_file(); $waitinp = 0; } elsif ( uc($inp) eq 'Q' ) { prt( "Quitting ... with no pass update ...\n" ); $waitinp = 0; } elsif ( uc(substr($inp,0,2)) eq 'U=' ) { $usrname = substr($inp,2); prt( "Set User Name to [$usrname] ...\n" ); } else { prt( "Cycle for NEXT password generation ...\n" ); push(@prevpasses, $finalpwd); $cntuc = 0; # kill this to enter ... get_password(); } } } exit(0); # ZERO is SUCCESS pwd generation ... sub prt { my ($txt) = shift; print $txt; } sub mydie { my ($txt) = shift; prt($txt); exit(1); } # eof - genpass.pl