Cover V11, I07

Article
Listing 1

jul2002.tar

Listing 1 Copy this file, make it executable, and put it where your users can find it (usually /usr/local/bin).

#!/usr/bin/perl -w

# Easypass.pl
# Version: 1.0
# Author: Matt Lesko, matt@advancedatatools.com http://mattlesko.dyndns.org:8080
# Inspired by:  Mark A. Pors's Sort-of-pronouncable (SoP) password generator 
#         mark@dreamzpace.com, www.dreamzpace.com
# License: GPL
# http://www.gnu.org/copyleft/gpl.html

use strict;
use Getopt::Long;

my $dictionary = '/usr/dict/words';       # path to dict file (site dependent)

# This are the option variables, they will be undefined or 0 is no option is set
my $help = '';        # Will be true if -h or --help is specified
my $oneword = '';     # Will be true if -1 or --oneword is specified
my $number = '';      # Will be true if -n or --number is specified
my $usespecial = '';  # Will be true if -s or --special is specified
my $usel33t = '';     # Will be true if -l or --l33t is specified
my $wordlength = 0;   # Will be true if -w=x or --word=x is specified (default: 5)
my $digitlength = 0;  # Will be true if -d=x or --digit=x is specified (default: 2)
my $speciallength = 0; # Will be true if -g=x or --slength=x is specified (default: 1)
my $numwords = 0;  # Will be true if -p=x or --passwords=x is specified (default: 10)

GetOptions ('h|help|?' => \$help, '1|oneword' => \$oneword, 'n|number' => 
\$number, 's|special' => \$usespecial, 'l|l33t' => \$usel33t, 'w|word=i' => 
\$wordlength, 'd|digit=i' => \$digitlength, 'g|slength=i' => \$speciallength, 
'p|passwords=i' => \$numwords);

if($help)
{
    print "\n\n";
    print "Usage: $0 [options] \n\n";
    print "Prints out a list of semi-memorable password for your choosing.\n";
    print "The following options are supported:\n\n";    
    print " -h, --help         Print this message\n";
    print " -1, --oneword      Prints only one random word (default: two)\n";
    print " -n, --number       Prints a random number (default: does not)\n";
    print " -s, --special      Prints out a 'special' character (&, #, etc.)\n";
    print " -l, --l33t         Forces the passwords to have 'l33t-sp34k'\n";
    print " -w=x, --word=x     Forces the words to be x characters (def:5, 
                                 min:3, max:8)\n";
    print " -d=x, --digit=x    Forces the number of digits to be x(def:2, 
                                 max:8)\n";
    print " -g=x, --slength=x  Forces the number of special characters to x 
                                 (def:1, max:8)\n";
    print " -p=x, --passwords=x Forces the number of passwords printed to be x 
                                 (def:10)\n\n";

    print "Please send any questions/comments/bugs to matt\@advancedatatools.com\n";
    exit;
}


my @special = ('~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '-', '+', '=');
my @dict;

open (DICT, "<$dictionary") || die ("Cannot open dict: $!, dictionary is located 
                                     at $dictionary, according to this program; 
                                     try changing this to your system.");
while (<DICT>) {
    chomp;
    push (@dict, $_);
}

# If the user gave us a number, use that; else, default to 10
if($numwords == 0) {
    $numwords = 10;
} elsif ($numwords < 0) {
    $numwords = 1; 
}

# If the user gave us a wordlength, use that; else, default to 5, also, make 
# sure that the number is between 3 and 8

if($wordlength == 0) {
    $wordlength = 5;
} elsif ($wordlength > 8) {
    $wordlength = 8;
} elsif ($wordlength < 3) {
    $wordlength = 3;
}

# Parts is a variable that lets us build the password to the desired length
my $parts = 0;
if($wordlength > 4) {
    $parts = int(8/$wordlength);
} else {
    $parts = int(3/$wordlength);
}

# This begins the main program loop, does this until we've done as many 
for (my $j=0;$j<$numwords;$j++) {

    my @sub = ();
    my $word = '';

# We get the first word here, and truncate it to 6; may change this (delete $sublen)

    for (my $i=0;$i < $parts; $i++) {
    do {
        $sub[$i] = substr ($dict[int (rand @dict)], 0);
    }
    until (length $sub[$i] == $wordlength);
    $word .= lc $sub[$i];
    }

# Here we take two numbers, if the user wants it, and insert it after the word
if($number) {
    if($digitlength == 0) {
    $digitlength = 2;
    } elsif ($digitlength < 1) {
    $digitlength = 1;
    } elsif ($digitlength > 8) {
    $digitlength = 8;
    }
    $word .= substr (int rand (10**(10)), 0, $digitlength);
}

# Here we put the special character(s) in, if the user wanted us too
if($usespecial) {

    if($speciallength == 0) {
    $speciallength = 1;
    } elsif ($speciallength < 1) {
    $speciallength = 1;
    } elsif ($speciallength > 8) {
    $speciallength = 8;
    }

    for(my $l=0; $l<$speciallength; $l++) {
        $word .= substr ($special[int (rand @special)], 0);
    }
}

# Here we get the last word, unless they told us not too; plus it may not matter 
# for some systems (most UNIX boxes only take 8 characters)

unless($oneword){

    for (my $i=0;$i < $parts; $i++) {
    do {
        $sub[$i] = substr ($dict[int (rand @dict)], 0);
    }
    until (length $sub[$i] == $wordlength);
    $word .= lc $sub[$i];
    }
}

# Here we convert to l33t-sp34k; e->3, o->0, i->1, a->4, t->7, s->$ (any others?)
if($usel33t) {
    $word =~ s/e+/3/;
    $word =~ s/o+/0/;
    $word =~ s/i+/1/;
    $word =~ s/a+/4/;
    $word =~ s/t+/7/;
    $word =~ s/s+/\$/;
}

    print "$word\n";
}