PE_OK
PE_ERROR
PE_PP_PASSWORD_TOO_LONG
PE_PP_PASSWORD_TOO_SHORT
PE_PP_NOT_ALLOWED_CHARACTER
PE_PP_NOT_ALLOWED_CHARACTERS
PE_PP_INSUFFICIENT_PASSWORD_QUALITY
)
;
our
$VERSION
=
'2.20.0'
;
use
constant
hook
=> {
passwordBeforeChange
=>
'checkPasswordQuality'
, };
has
pwdPolicyRule
=> (
is
=>
'rw'
);
sub
init {
my
(
$self
) =
@_
;
my
$pwdPolicyRule
=
$self
->p->buildRule(
$self
->conf->{passwordPolicyActivation},
"Password policy activation rule"
);
$self
->pwdPolicyRule(
$pwdPolicyRule
);
return
0
unless
$pwdPolicyRule
;
$self
->p->addPasswordPolicyDisplay(
'ppolicy-minsize'
,
{
condition
=>
$self
->conf->{passwordPolicyMinSize},
value
=>
$self
->conf->{passwordPolicyMinSize},
label
=>
"passwordPolicyMinSize"
,
order
=> 101,
}
);
$self
->p->addPasswordPolicyDisplay(
'ppolicy-minlower'
,
{
condition
=>
$self
->conf->{passwordPolicyMinLower},
value
=>
$self
->conf->{passwordPolicyMinLower},
label
=>
"passwordPolicyMinLower"
,
order
=> 102,
}
);
$self
->p->addPasswordPolicyDisplay(
'ppolicy-minupper'
,
{
condition
=>
$self
->conf->{passwordPolicyMinUpper},
value
=>
$self
->conf->{passwordPolicyMinUpper},
label
=>
"passwordPolicyMinUpper"
,
order
=> 103,
}
);
$self
->p->addPasswordPolicyDisplay(
'ppolicy-mindigit'
,
{
condition
=>
$self
->conf->{passwordPolicyMinDigit},
value
=>
$self
->conf->{passwordPolicyMinDigit},
label
=>
"passwordPolicyMinDigit"
,
order
=> 104,
}
);
$self
->p->addPasswordPolicyDisplay(
'ppolicy-minspechar'
,
{
condition
=> (
$self
->conf->{passwordPolicyMinSpeChar}
&&
$self
->conf->{passwordPolicySpecialChar}
),
value
=>
$self
->conf->{passwordPolicyMinSpeChar},
label
=>
"passwordPolicyMinSpeChar"
,
order
=> 105,
}
);
$self
->p->addPasswordPolicyDisplay(
'ppolicy-allowedspechar'
,
{
condition
=> (
$self
->conf->{passwordPolicyMinSpeChar} &&
$self
->p->speChars()
),
value
=>
$self
->p->speChars(),
label
=>
"passwordPolicySpecialChar"
,
order
=> 106,
}
);
$self
->p->addPasswordPolicyDisplay(
'ppolicy-maxsize'
,
{
condition
=>
$self
->conf->{passwordPolicyMaxSize},
value
=>
$self
->conf->{passwordPolicyMaxSize},
label
=>
"passwordPolicyMaxSize"
,
order
=> 107,
}
);
return
1;
}
sub
checkPasswordQuality {
my
(
$self
,
$req
,
$user
,
$password
,
$old
) =
@_
;
if
(
$self
->pwdPolicyRule->(
$req
,
$req
->userData ) ) {
$self
->logger->debug(
"Checking basic password policy for $user"
);
return
$self
->checkBasicPolicy(
$password
);
}
else
{
$self
->logger->debug(
"Skipping basic password policy for $user"
);
return
PE_OK;
}
}
sub
checkBasicPolicy {
my
(
$self
,
$password
,
$old
) =
@_
;
if
(
$self
->conf->{passwordPolicyMinSize}
and
length
(
$password
) <
$self
->conf->{passwordPolicyMinSize} )
{
$self
->logger->error(
"Password too short"
);
return
PE_PP_PASSWORD_TOO_SHORT;
}
if
(
$self
->conf->{passwordPolicyMaxSize}
and
length
(
$password
) >
$self
->conf->{passwordPolicyMaxSize} )
{
$self
->logger->error(
"Password too long"
);
return
PE_PP_PASSWORD_TOO_LONG;
}
if
(
$self
->conf->{passwordPolicyMinLower} ) {
my
$lower
= 0;
$lower
++
while
(
$password
=~ m/\p{lowercase}/g );
if
(
$lower
<
$self
->conf->{passwordPolicyMinLower} ) {
$self
->logger->error(
"Password has not enough lower characters"
);
return
PE_PP_INSUFFICIENT_PASSWORD_QUALITY;
}
}
if
(
$self
->conf->{passwordPolicyMinUpper} ) {
my
$upper
= 0;
$upper
++
while
(
$password
=~ m/\p{uppercase}/g );
if
(
$upper
<
$self
->conf->{passwordPolicyMinUpper} ) {
$self
->logger->error(
"Password has not enough upper characters"
);
return
PE_PP_INSUFFICIENT_PASSWORD_QUALITY;
}
}
if
(
$self
->conf->{passwordPolicyMinDigit} ) {
my
$digit
= 0;
$digit
++
while
(
$password
=~ m/\d/g );
if
(
$digit
<
$self
->conf->{passwordPolicyMinDigit} ) {
$self
->logger->error(
"Password has not enough digit characters"
);
return
PE_PP_INSUFFICIENT_PASSWORD_QUALITY;
}
}
my
$speChars
=
$self
->conf->{passwordPolicySpecialChar};
if
(
$self
->conf->{passwordPolicyMinSpeChar} &&
$speChars
eq
'__ALL__'
) {
my
$spe
=
$password
=~ s/[\W_]//g;
if
(
$spe
<
$self
->conf->{passwordPolicyMinSpeChar} ) {
$self
->logger->error(
"Password has not enough special characters"
);
return
PE_PP_INSUFFICIENT_PASSWORD_QUALITY;
}
return
PE_OK;
}
if
(
$self
->conf->{passwordPolicyMinSpeChar} &&
$speChars
) {
my
$test
=
$password
;
my
$spe
=
$test
=~ s/[\Q
$speChars
\E]//g;
if
(
$spe
<
$self
->conf->{passwordPolicyMinSpeChar} ) {
$self
->logger->error(
"Password has not enough special characters"
);
return
PE_PP_INSUFFICIENT_PASSWORD_QUALITY;
}
}
unless
(
$speChars
eq
'__ALL__'
) {
$password
=~ s/[\Q
$speChars
\E\w]//g;
if
(
$password
) {
$self
->logger->error(
'Password contains '
.
length
(
$password
)
.
" forbidden character(s): $password"
);
return
length
(
$password
) > 1
? PE_PP_NOT_ALLOWED_CHARACTERS
: PE_PP_NOT_ALLOWED_CHARACTER;
}
}
return
PE_OK;
}
1;