File Coverage

blib/lib/Mail/PopPwd.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             #
2             # PopPwd.pm
3             # Last Modification: Fri Oct 10 18:31:17 WEST 2003
4             #
5             # Copyright (c) 2002 Henrique Dias . All rights reserved.
6             # This module is free software; you can redistribute it and/or modify
7             # it under the same terms as Perl itself.
8             #
9              
10             package Mail::PopPwd;
11 1     1   792 use strict;
  1         2  
  1         49  
12             require Exporter;
13 1     1   5 use vars qw($VERSION @ISA @EXPORT);
  1         1  
  1         92  
14             @ISA = qw(Exporter AutoLoader);
15             $VERSION = 0.03;
16             @ISA = qw(Exporter);
17             require 5;
18 1     1   874 use IO::Socket;
  1         32754  
  1         4  
19 1     1   2332 use Crypt::Cracklib;
  0            
  0            
20              
21             sub new {
22             my $proto = shift;
23             my $class = ref($proto) || $proto;
24             my $self = {
25             HOST => "localhost",
26             PORT => 106,
27             TIMEOUT => 0,
28             USER => "",
29             NAME => "",
30             STOREDPWD => "",
31             OLDPWD => "",
32             NEWPWD => "",
33             CONFPWD => "",
34             NMIN => 6,
35             NMAX => 12,
36             NDIFCHARS => 4,
37             NSEQWORD => 4,
38             CRACKLIB => "",
39             @_,
40             };
41             bless ($self, $class);
42             return($self);
43             }
44              
45             sub count_chars {
46             my $string = shift;
47              
48             my %seen;
49             my @chars = split(//, $string);
50             @seen{@chars} = ();
51             return(scalar(keys(%seen)));
52             }
53              
54             sub checkpwd {
55             my $self = shift;
56              
57             $self->{USER} or return(551);
58             $self->{OLDPWD} or return(551);
59             $self->{NEWPWD} or return(553);
60             $self->{CONFPWD} or return(554);
61             return(555) if(length($self->{NEWPWD}) < $self->{NMIN});
62             return(556) if(length($self->{NEWPWD}) > $self->{NMAX});
63             return(557) if($self->{NEWPWD} ne $self->{CONFPWD});
64             return(558) if($self->{STOREDPWD} && ($self->{OLDPWD} ne $self->{STOREDPWD}));
65             return(559) if(&count_chars($self->{NEWPWD}) < $self->{NDIFCHARS});
66              
67             my $pwdrev = reverse($self->{NEWPWD});
68             return(560) if(&check_dif($self->{NEWPWD},$self->{OLDPWD},$self->{NSEQWORD}) || &check_dif($pwdrev,$self->{OLDPWD},$self->{NSEQWORD}));
69             return(561) if(&check_dif($self->{NEWPWD},$self->{USER},$self->{NSEQWORD}) || &check_dif($pwdrev,$self->{USER},$self->{NSEQWORD}));
70             return(562) if($self->{NAME} &&
71             (&check_dif($self->{NEWPWD}, $self->{NAME},$self->{NSEQWORD}) ||
72             &check_dif($pwdrev, $self->{NAME}, $self->{NSEQWORD})));
73              
74             if($self->{CRACKLIB}) {
75             my $reason = fascist_check($self->{NEWPWD}, $self->{CRACKLIB});
76             chomp($reason);
77             ($reason eq "ok") or return(563);
78             }
79             return();
80             }
81              
82             sub change {
83             my $self = shift;
84              
85             my $socket = IO::Socket::INET->new(
86             PeerAddr => $self->{HOST},
87             PeerPort => $self->{PORT},
88             Proto => "tcp",
89             Type => SOCK_STREAM,
90             Timeout => $self->{TIMEOUT}
91             ) or return(join("", "Couldn't connect to ", $self->{HOST}, ":", $self->{PORT}, " $@\n"));
92              
93             my $EOL = "\015\012";
94             my $error = "";
95             TEST: {
96             print $socket join(" ", "user", $self->{USER}), $EOL;
97             last TEST if($error = &get_answer($socket));
98             print $socket join(" ", "pass", $self->{OLDPWD}), $EOL;
99             last TEST if($error = &get_answer($socket));
100             print $socket join(" ", "newpass", $self->{NEWPWD}), $EOL;
101             last TEST if($error = &get_answer($socket));
102             print $socket "quit$EOL";
103             last TEST if($error = &get_answer($socket));
104             }
105             close($socket);
106             return($error);
107             }
108              
109             sub get_answer {
110             my $answer = shift;
111             my $line = <$answer>;
112             my $v = substr($line,0,3);
113             return(($v eq "200") ? "" : $line);
114             }
115              
116             sub check_dif($$$) {
117             my($str1, $str2, $n) = @_;
118              
119             ($str1, $str2) = ($str2, $str1) if(length($str2) < length($str1));
120             my @parts = $str1 =~ /(?=(.{$n}))/g;
121             for(@parts) { return($_) if($str2 =~ /\Q$_\E/ig); }
122             return();
123             }
124              
125             1;
126              
127             __END__