Data-Password-1.08/0000755000175000001440000000000012171043324012742 5ustar odedusersData-Password-1.08/MANIFEST0000644000175000001440000000032110464641611014075 0ustar odedusersChanges Makefile.PL MANIFEST Password.pm t/IsBadPasswordForUNIX.t t/IsBadPassword.t t/words Dummy dictionary for tests README META.yml Module meta-data (added by MakeMaker) Data-Password-1.08/Changes0000644000175000001440000000163312171043166014244 0ustar odedusersRevision history for Perl extension Data::Password. 0.01 Wed Jan 16 17:26:03 2002 - original version; created by h2xs 1.19 1.03 Sat Apr 3 23:50:12 2004 - Added new variable @DICTIONARIES - Documentation updated 1.04 Sat Aug 7 11:28:11 IDT 2004 - Fixed error message for $MAXLEN==0 (thanks to James Saint-Rossy who submitted a patch) 1.05 Sat Aug 7 22:47:42 IDT 2004 - Fixed test.pl to work on platforms with no dictionaries. (Thanks to 'Barbie' from cpan-testers) 1.06 Wed Aug 2 22:14:35 IDT 2006 - Added dummy dictionary. - Stricter dictionary checking (Requested by Gary Bennett) If your dictionary has entries with '.' password is not checked against these entries. 1.07 Fri Aug 4 13:18:42 IDT 2006 - CheckDict optimized for speed. - Symbol::gensym remmoved. 1.08 Mon Jul 15 21:35:11 IDT 2013 - minor documentation update (by Neil Bowers) Data-Password-1.08/README0000644000175000001440000000571412171042000013617 0ustar odedusersNAME Data::Password - Perl extension for assessing password quality. SYNOPSIS use Data::Password qw(IsBadPassword); print IsBadPassword("clearant"); # Bad password - contains the word 'clear', only lowercase use Data::Password qw(:all); $DICTIONARY = 0; $GROUPS = 0; print IsBadPassword("clearant"); DESCRIPTION This module checks potential passwords for crackability. It checks that the password is in the appropriate length, that it has enough character groups, that it does not contain the same characters repeatedly or ascending or descending characters, or charcters close to each other in the keyboard. It will also attempt to search the ispell word file for existance of whole words. The module's policies can be modified by changing its variables. (Check "VARIABLES"). For doing it, it is recommended to import the ':all' shortcut when requiring it: *use Data::Password qw(:all);* FUNCTIONS 1 IsBadPassword(password) Returns undef if the password is ok, or a textual description of the fault if any. 2 IsBadPasswordForUNIX(user, password) Performs two additional checks: compares the password against the login name and the "comment" (ie, real name) found on the user file. VARIABLES 1 $DICTIONARY Minimal length for dictionary words that are not allowed to appear in the password. Set to false to disable dictionary check. 2 $FOLLOWING Maximal length of characters in a row to allow if the same or following. If $FOLLOWING_KEYBOARD is true (default), the module will also check for alphabetical keys following, according to the English keyboard layout. Set $FOLLOWING to false to bypass this check. 3 $GROUPS Groups of characters are lowercase letters, uppercase letters, digits and the rest of the allowed characters. Set $GROUPS to the number of minimal character groups a password is required to have. Setting to false or to 1 will bypass the check. 4 $MINLEN $MAXLEN Minimum and maximum length of a password. Both can be set to false. 5 @DICTIONARIES Location where we are looking for dictionary files. You may want to set this variable if you are using not *NIX like operating system. FILES * /usr/dict/web2 * /usr/dict/words * /etc/passwd SEE ALSO See Data::Password::BasicCheck if you need only basic password checking. Other modules Data::Password::Common, Data::Password::Check, Data::Password::Meter, Data::Password::Entropy and String::Validator::Password AUTHOR Raz Information Systems, razinf@cpan.org COPYRIGHT Copyright (c) 2001 - 2013 Raz Information Systems Ltd. This package is distributed under the same terms as Perl itself, see the Artistic License on Perl's home page. Data-Password-1.08/Password.pm0000644000175000001440000001410212171041717015104 0ustar odeduserspackage Data::Password; # Ariel Brosh (RIP), January 2002, for Raz Information Systems # Oded S. Resnik, 3 April 2004, for Raz Information Systems use strict; require Exporter; use vars qw($DICTIONARY $FOLLOWING $GROUPS $MINLEN $MAXLEN $FOLLOWING_KEYBOARD @DICTIONARIES $VERSION @ISA @EXPORT_OK %EXPORT_TAGS); @EXPORT_OK = qw($DICTIONARY $FOLLOWING $GROUPS $FOLLOWING_KEYBOARD @DICTIONARIES $MINLEN $MAXLEN IsBadPassword IsBadPasswordForUNIX); %EXPORT_TAGS = ('all' => [@EXPORT_OK]); @ISA = qw(Exporter); $VERSION = '1.08'; $DICTIONARY = 5; $FOLLOWING = 3; $FOLLOWING_KEYBOARD = 1; $GROUPS = 2; $MINLEN = 6; $MAXLEN = 8; @DICTIONARIES = qw(/usr/dict/web2 /usr/dict/words /usr/share/dict/words /usr/share/dict/linux.words); sub OpenDictionary { foreach my $sym (@DICTIONARIES) { return $sym if -r $sym; } return; } sub CheckDict { return unless $DICTIONARY; my $pass = shift; my $dict = OpenDictionary(); return unless $dict; open (DICT,"$dict") || return; $pass = lc($pass); while (my $dict_line = ) { chomp ($dict_line); next if length($dict_line) < $DICTIONARY; $dict_line = lc($dict_line); if (index($pass,$dict_line)>-1) { close(DICT); return $dict_line; } } close(DICT); return; } sub CheckSort { return unless $FOLLOWING; my $pass = shift; foreach (1 .. 2) { my @letters = split(//, $pass); my $diffs; my $last = shift @letters; foreach (@letters) { $diffs .= chr((ord($_) - ord($last) + 256 + 65) % 256); $last = $_; } my $len = $FOLLOWING - 1; return 1 if $diffs =~ /([\@AB])\1{$len}/; return unless $FOLLOWING_KEYBOARD; my $mask = $pass; $pass =~ tr/A-Z/a-z/; $mask ^= $pass; $pass =~ tr/qwertyuiopasdfghjklzxcvbnm/abcdefghijKLMNOPQRStuvwxyz/; $pass ^= $mask; } return; } sub CheckTypes { return undef unless $GROUPS; my $pass = shift; my @groups = qw(a-z A-Z 0-9 ^A-Za-z0-9); my $count; foreach (@groups) { $count++ if $pass =~ /[$_]/; } $count < $GROUPS; } sub CheckCharset { my $pass = shift; $pass =~ /[\0-\x1F \x7F]/; } sub CheckLength { my $pass = shift; my $len = length($pass); return 1 if ($MINLEN && $len < $MINLEN); return 1 if ($MAXLEN && $len > $MAXLEN); return; } sub IsBadPassword { my $pass = shift; if (CheckLength($pass)) { if ($MAXLEN && $MINLEN) { return "Not between $MINLEN and $MAXLEN characters"; } elsif (!$MAXLEN) { return "Not $MINLEN characters or greater"; } else { return "Not less than or equal to $MAXLEN characters"; } } return "contains bad characters" if CheckCharset($pass); return "contains less than $GROUPS character groups" if CheckTypes($pass); return "contains over $FOLLOWING leading characters in sequence" if CheckSort($pass); my $dict = CheckDict($pass); return "contains the dictionary word '$dict'" if $dict; return; } sub IsBadPasswordForUNIX { my ($user, $pass) = @_; my $reason = IsBadPassword($pass); return $reason if $reason; my $tuser = $user; $tuser =~ s/[^a-zA-Z]//g; return "is based on the username" if ($pass =~ /$tuser/i); my ($name,$passwd,$uid,$gid, $quota,$comment,$gcos,$dir,$shell,$expire) = getpwnam($user); return unless $comment; foreach ($comment =~ /([A-Z]+)/ig) { return "is based on the finger information" if ($pass =~ /$_/i); } return; } 1; __END__ =head1 NAME Data::Password - Perl extension for assessing password quality. =head1 SYNOPSIS use Data::Password qw(IsBadPassword); print IsBadPassword("clearant"); # Bad password - contains the word 'clear', only lowercase use Data::Password qw(:all); $DICTIONARY = 0; $GROUPS = 0; print IsBadPassword("clearant"); =head1 DESCRIPTION This module checks potential passwords for crackability. It checks that the password is in the appropriate length, that it has enough character groups, that it does not contain the same characters repeatedly or ascending or descending characters, or charcters close to each other in the keyboard. It will also attempt to search the ispell word file for existance of whole words. The module's policies can be modified by changing its variables. (Check L<"VARIABLES">). For doing it, it is recommended to import the ':all' shortcut when requiring it: I =head1 FUNCTIONS =over 4 =item 1 IsBadPassword(password) Returns undef if the password is ok, or a textual description of the fault if any. =item 2 IsBadPasswordForUNIX(user, password) Performs two additional checks: compares the password against the login name and the "comment" (ie, real name) found on the user file. =back =head1 VARIABLES =over 4 =item 1 $DICTIONARY Minimal length for dictionary words that are not allowed to appear in the password. Set to false to disable dictionary check. =item 2 $FOLLOWING Maximal length of characters in a row to allow if the same or following. If $FOLLOWING_KEYBOARD is true (default), the module will also check for alphabetical keys following, according to the English keyboard layout. Set $FOLLOWING to false to bypass this check. =item 3 $GROUPS Groups of characters are lowercase letters, uppercase letters, digits and the rest of the allowed characters. Set $GROUPS to the number of minimal character groups a password is required to have. Setting to false or to 1 will bypass the check. =item 4 $MINLEN $MAXLEN Minimum and maximum length of a password. Both can be set to false. =item 5 @DICTIONARIES Location where we are looking for dictionary files. You may want to set this variable if you are using not *NIX like operating system. =back =head1 FILES =over 4 =item * /usr/dict/web2 =item * /usr/dict/words =item * /etc/passwd =back =head1 SEE ALSO See L if you need only basic password checking. Other modules L, L, L, L and L =head1 AUTHOR Raz Information Systems, B =head1 COPYRIGHT Copyright (c) 2001 - 2013 Raz Information Systems Ltd. L This package is distributed under the same terms as Perl itself, see the Artistic License on Perl's home page. =cut Data-Password-1.08/Makefile.PL0000644000175000001440000000073307430471772014735 0ustar odedusersuse ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. sub MY::postamble { package MY; shift->SUPER::postamble . <<'MAKE'; distdir : README README : Password.pm @$(PERL) -MPod::Text -e "pod2text('$<');" > $@ MAKE } WriteMakefile( 'NAME' => 'Data::Password', 'VERSION_FROM' => 'Password.pm', # finds $VERSION 'dist' => {'COMPRESS' => 'gzip --best --force'}, ); Data-Password-1.08/t/0000755000175000001440000000000012171043324013205 5ustar odedusersData-Password-1.08/t/IsBadPassword.t0000644000175000001440000000210210464674672016115 0ustar odedusers# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) use Test::More qw(no_plan); use Data::Password qw(IsBadPassword $MAXLEN @DICTIONARIES); ok(1,'Module Loaded'); my %tests = qw(BlaBla 1 blabla 0 cleaner 0 qwerTy 0 aB1234 0 xxxZZZ 1 xxxxZZ 0 Abramson 0 noboXX 1 MAxLEN1288457 0 MAXlen12r45f7 1 ); my $have_dic =0; my $dic_name = ''; #@DICTIONARIES = undef; @DICTIONARIES = qw(t/words words); foreach (@DICTIONARIES){ if (-r $_ && /words$/) { $have_dic = 1; $dic_name=$_; last; }; } ok($have_dic eq 1,"Dictionary '$dic_name' loaded"); $tests{Abramson} = $have_dic ? 0 : 1; while (my ($pass, $good) = each %tests) { $MAXLEN = $pass eq 'MAXlen12r45f7' ? 0 : 8; my $reason = IsBadPassword($pass) || ''; my $got = $reason ? 0 : 1; ok($got eq $good,"$pass: $reason"); } Data-Password-1.08/t/words0000644000175000001440000000001410464614535014274 0ustar odedusersAbram n.b.X Data-Password-1.08/t/IsBadPasswordForUNIX.t0000644000175000001440000000242110464674641017270 0ustar odedusers# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) use Test::More qw(no_plan); use Data::Password qw(IsBadPasswordForUNIX $MAXLEN @DICTIONARIES); ok(1,'Module Loaded'); eval { $_=getpwnam('IsBadPassword'); }; my $have_getpwnam = $@ ? 0 :1; my %tests = qw(BlaBla 1 blabla 0 cleaner 0 qwerTy 0 aB1234 0 xxxZZZ 1 xxxxZZ 0 Abramson 0 noboXX 1 MAxLEN1288457 0 MAXlen12r45f7 1 ); my $have_dic =0; my $dic_name = ''; #@DICTIONARIES = undef; @DICTIONARIES = qw(t/words words); foreach (@DICTIONARIES){ if (-r $_ && /words$/) { $have_dic = 1; $dic_name=$_; last; }; } ok($have_dic eq 1,"Dictionary '$dic_name' loaded"); SKIP: { skip 'No getpwnam on this platform',scalar(keys(%tests)) unless $have_getpwnam; $tests{Abramson} = $have_dic ? 0 : 1; while (my ($pass, $good) = each %tests) { $MAXLEN = $pass eq 'MAXlen12r45f7' ? 0 : 8; my $reason = IsBadPasswordForUNIX('IsBadPassword',$pass) || ''; my $got = $reason ? 0 : 1; ok($got eq $good,"$pass: $reason"); } } Data-Password-1.08/META.yml0000644000175000001440000000073212171043324014215 0ustar odedusers--- #YAML:1.0 name: Data-Password version: 1.08 abstract: ~ author: [] license: unknown distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: {} no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.57_05 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4