Data-Password-1.12/0000755000175000001440000000000012456300243012737 5ustar odedusersData-Password-1.12/Password.pm0000644000175000001440000001514112456276720015115 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 $SKIPCHAR $FOLLOWING_KEYBOARD @DICTIONARIES $BADCHARS $VERSION @ISA @EXPORT_OK %EXPORT_TAGS); @EXPORT_OK = qw($DICTIONARY $FOLLOWING $GROUPS $FOLLOWING_KEYBOARD $SKIPCHAR $BADCHARS @DICTIONARIES $MINLEN $MAXLEN IsBadPassword IsBadPasswordForUNIX); %EXPORT_TAGS = ('all' => [@EXPORT_OK]); @ISA = qw(Exporter); $VERSION = '1.12'; # Settings $DICTIONARY = 5; $FOLLOWING = 3; $FOLLOWING_KEYBOARD = 1; $GROUPS = 2; $MINLEN = 6; $MAXLEN = 8; $SKIPCHAR = 0; $BADCHARS = '\0-\x1F\x7F'; @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; return 0 if $SKIPCHAR; $pass =~ /[$BADCHARS]/; } 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; $SKIPCHAR = 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. =item 6 $SKIPCHAR Set $SKIPCHAR to 1 to skip checking for bad characters. =item 7 $BADCHARS Prohibit a specific character range. Excluded character range regualr experssion is expect. (You may use ^ to allow specific range) Default value is: '\0-\x1F\x7F' For ASCII only set value $BADCHARS = '^\x20-\x7F'; Force numbers and upper case only $BADCHARS = '^A-Z1-9'; =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 Ariel Brosh (RIP), January 2002. Oded S. Resnik, from April 2004. =head1 COPYRIGHT Copyright (c) 2001 - 2014 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.12/META.yml0000644000175000001440000000071012456300243014206 0ustar odedusers--- abstract: unknown author: - unknown build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Data-Password no_index: directory: - t - inc requires: Exporter: 0 Test::More: 0 version: 1.12 Data-Password-1.12/Makefile.PL0000644000175000001440000000106112425244662014717 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 PREREQ_PM => { 'Test::More' => 0, 'Exporter' => 0, }, 'dist' => {'COMPRESS' => 'gzip --best --force'}, ); Data-Password-1.12/README0000644000175000001440000000665112456277476013654 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; $SKIPCHAR = 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. 6 $SKIPCHAR Set $SKIPCHAR to 1 to skip checking for bad characters. 7 $BADCHARS Prohibit a specific character range. Excluded character range regualr experssion is expect. (You may use ^ to allow specific range) Default value is: '\0-\x1F\x7F' For ASCII only set value $BADCHARS = '^\x20-\x7F'; Force numbers and upper case only $BADCHARS = '^A-Z1-9'; 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 Ariel Brosh (RIP), January 2002. Oded S. Resnik, from April 2004. COPYRIGHT Copyright (c) 2001 - 2014 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.12/MANIFEST0000644000175000001440000000047312456300243014074 0ustar odedusersChanges Makefile.PL MANIFEST Password.pm t/IsBadPasswordForUNIX.t t/IsBadPasswordChar.t t/IsBadPassword.t t/words Dummy dictionary for tests README META.yml Module meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Data-Password-1.12/t/0000755000175000001440000000000012456300243013202 5ustar odedusersData-Password-1.12/t/IsBadPassword.t0000644000175000001440000000224212456275613016110 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 $SKIPCHAR); 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 ); # Bad space test $tests{"I Glxi"} = 1; # Bad char test $tests{"\0BC2f4a"} = 0; 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.12/t/IsBadPasswordForUNIX.t0000644000175000001440000000242110464674641017263 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.12/t/words0000644000175000001440000000001410464614535014267 0ustar odedusersAbram n.b.X Data-Password-1.12/t/IsBadPasswordChar.t0000644000175000001440000000166512456277357016725 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' ################################################################### use Test::More qw(no_plan); use Data::Password qw(IsBadPassword $MAXLEN @DICTIONARIES $SKIPCHAR $BADCHARS); ok(1,'Module Loaded'); { my $pass = "\0BC2f4a"; my $reason = IsBadPassword($pass) || ''; ok($reason ,"$pass: $reason"); $SKIPCHAR = 1; my $reason = IsBadPassword($pass) || ''; ok(! $reason ,"$pass: $reason"); $SKIPCHAR = 0; } { $SKIPCHAR = 0; my $pass = "0BC2f4a"; my $reason = IsBadPassword($pass) || ''; ok(! $reason ,"$pass: $reason"); $BADCHARS = '^A-Z1-9'; $reason = IsBadPassword($pass) || ''; ok($reason ,"$pass: $reason"); $pass = "BCAFDQ11"; $reason = IsBadPassword($pass) || ''; ok(! $reason ,"$pass: $reason"); } Data-Password-1.12/Changes0000644000175000001440000000266712456300235014246 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 removed. 1.08 Mon Jul 15 21:35:11 IDT 2013 - Minor documentation update (by Neil Bowers) 1.09 Sat Apr 26 09:42:11 IST 2014 1.10 Sat Apr 26 16:39:11 IST 2014 - Passwords contains a space character (by Frederic Van Espen) - new variable ($SKIPCHAR) to skip bad character check. 1.11 Sat Nov 1 22:51:19 IST 2014 - Added dependency for Test::More to faciliate install on RedHat platform - Added dependency for Exported added as adviced by Gabor Szabo 1.12 Fri Jan 16 23:14:11 IST 2015 - new variable ($BADCHARS) allow users to decide valid characters (Requested by Frederic Van Espen) Data-Password-1.12/META.json0000644000175000001440000000153612456300243014365 0ustar odedusers{ "abstract" : "unknown", "author" : [ "unknown" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Data-Password", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Exporter" : "0", "Test::More" : "0" } } }, "release_status" : "stable", "version" : "1.12" }