- Build password strength enforcer as an implementation of ppolicy

password checker, introducing:
  ppolicy-check-password-1.2.tar.gz
  ppolicy-check-password.Makefile
  ppolicy-check-password.conf
  ppolicy-check-password.5
  0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch
  (Implements fate#319461)

OBS-URL: https://build.opensuse.org/package/show/network:ldap/openldap2?expand=0&rev=155
This commit is contained in:
Howard Guo 2016-02-18 15:54:30 +00:00 committed by Git OBS Bridge
parent 7ed736ced1
commit 7ecd27d588
7 changed files with 439 additions and 1 deletions

View File

@ -0,0 +1,130 @@
From b026c9236e6b11c158e69572a28eb0efb174234b Mon Sep 17 00:00:00 2001
From: HouzuoGuo <guohouzuo@gmail.com>
Date: Wed, 17 Feb 2016 16:10:05 +0100
Subject: [PATCH] Fix incorrect calculation of consecutive number of characters
in a class, when the input is shorter than 6 chars or consecutive chars
appear at the beginning of input
diff --git a/check_password.c b/check_password.c
index 0d9f901..acf8eda 100644
--- a/check_password.c
+++ b/check_password.c
@@ -355,18 +355,7 @@ check_password (char *pPasswd, char **ppErrStr, Entry *pEntry)
int min_quality = DEFAULT_QUALITY;
int use_cracklib = DEFAULT_CRACKLIB;
- /** bail out early as cracklib will reject passwords shorter
- * than 6 characters
- */
-
nLen = strlen (pPasswd);
- if ( nLen < 6) {
- mem_len = realloc_error_message(&szErrStr, mem_len,
- strlen(PASSWORD_TOO_SHORT_SZ) +
- strlen(pEntry->e_name.bv_val) + 1);
- sprintf (szErrStr, PASSWORD_TOO_SHORT_SZ, pEntry->e_name.bv_val, nLen);
- goto fail;
- }
if (read_config_file() == -1) {
syslog(LOG_ERR, "Warning: Could not read values from config file %s. Using defaults.", CONFIG_FILE);
@@ -392,46 +381,38 @@ check_password (char *pPasswd, char **ppErrStr, Entry *pEntry)
*/
if ( max_consecutive_per_class != 0 ) {
- int consec_chars = 1;
- char type[10] = "unkown";
- char prev_type[10] = "unknown";
+ char prev_type = '\0';
+ char this_type = ' ';
+ i = 0;
+ int consec_chars = 0;
for ( i = 0; i < nLen; i++ ) {
-
if ( islower(pPasswd[i]) ) {
- strncpy(type,"lower",10);
+ this_type = 'l';
}
else if ( isupper(pPasswd[i]) ) {
- strncpy(type,"upper",10);
+ this_type = 'u';
}
else if ( isdigit(pPasswd[i]) ) {
- strncpy(type,"digit",10);
+ this_type = 'd';
}
else if ( ispunct(pPasswd[i]) ) {
- strncpy(type,"punct",10);
+ this_type = 'p';
}
else {
- strncpy(type,"unknown",10);
- }
-
- if ( consec_chars > max_consecutive_per_class ) {
- mem_len = realloc_error_message(&szErrStr, mem_len,
- strlen(CONSEC_FAIL_SZ) +
- strlen(pEntry->e_name.bv_val));
- sprintf (szErrStr, CONSEC_FAIL_SZ, pEntry->e_name.bv_val);
- goto fail;
+ this_type = ' ';
}
-
- if ( strncmp(type,prev_type,10) == 0 ) {
- consec_chars++;
+ if (this_type == prev_type) {
+ ++consec_chars;
+ } else if (i > 0) {
+ consec_chars = 0;
}
- else {
- if (strncmp("unknown",prev_type,8) != 0) {
- consec_chars = 1;
- }
- else {
- consec_chars++;
- }
- strncpy(prev_type,type,10);
+ prev_type = this_type;
+ if ( consec_chars >= max_consecutive_per_class ) {
+ mem_len = realloc_error_message(&szErrStr, mem_len,
+ strlen(CONSEC_FAIL_SZ) +
+ strlen(pEntry->e_name.bv_val));
+ sprintf (szErrStr, CONSEC_FAIL_SZ, pEntry->e_name.bv_val);
+ goto fail;
}
}
}
diff --git a/check_password_test.c b/check_password_test.c
index 626d719..d33bd80 100644
--- a/check_password_test.c
+++ b/check_password_test.c
@@ -90,7 +90,6 @@ void setconf(
}
int main(void) {
-
// Empty Config, equiv to:
// 5,3,1,0,0,0,0
setconf(-1,-1,-1,-1,-1,-1,-1);
@@ -109,5 +108,16 @@ int main(void) {
testpass("Test 2.1", "Simp1e", 1);
testpass("Test 2.2", "SimPle", 1);
testpass("Test 2.1", "Simp1e!", 0);
+
+ setconf(1,0,0,0,0,0,0);
+ testpass("a", "Ab1,", 0);
+ testpass("a", "AAb1,", 1);
+ testpass("a", "Abb1,", 1);
+
+ setconf(3,0,0,0,0,0,0);
+ testpass("a", "AAAbbb111,,,", 0);
+ testpass("a", "AAAAbbb111,,,,", 1);
+ testpass("a", "AAAbbbb111,,,", 1);
+
return 0;
}
--
2.7.1

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Thu Feb 18 14:45:30 UTC 2016 - hguo@suse.com
- Build password strength enforcer as an implementation of ppolicy
password checker, introducing:
ppolicy-check-password-1.2.tar.gz
ppolicy-check-password.Makefile
ppolicy-check-password.conf
ppolicy-check-password.5
0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch
(Implements fate#319461)
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Feb 18 12:18:13 UTC 2016 - lmuelle@suse.com Thu Feb 18 12:18:13 UTC 2016 - lmuelle@suse.com

View File

@ -25,6 +25,10 @@
%define _rundir /var/run/slapd %define _rundir /var/run/slapd
%endif %endif
%define name_ppolicy_check_module ppolicy-check-password
%define version_ppolicy_check_module 1.2
%define ppolicy_docdir %{_docdir}/openldap-%{name_ppolicy_check_module}-%{version_ppolicy_check_module}
Name: openldap2 Name: openldap2
Summary: An open source implementation of the Lightweight Directory Access Protocol Summary: An open source implementation of the Lightweight Directory Access Protocol
License: OLDAP-2.8 License: OLDAP-2.8
@ -59,6 +63,12 @@ Patch8: 0008-In-monitor-backend-do-not-return-Connection0-entries.patch
Patch9: 0009-Fix-ldap-host-lookup-ipv6.patch Patch9: 0009-Fix-ldap-host-lookup-ipv6.patch
Patch10: 0010-Enforce-minimum-DH-size-of-1024.patch Patch10: 0010-Enforce-minimum-DH-size-of-1024.patch
Patch11: 0011-openldap-re24-its7796.patch Patch11: 0011-openldap-re24-its7796.patch
Source200: %{name_ppolicy_check_module}-%{version_ppolicy_check_module}.tar.gz
Source201: %{name_ppolicy_check_module}.Makefile
Source202: %{name_ppolicy_check_module}.conf
Source203: %{name_ppolicy_check_module}.5
Patch200: 0200-Fix-incorrect-calculation-of-consecutive-number-of-c.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: cyrus-sasl-devel BuildRequires: cyrus-sasl-devel
BuildRequires: db-devel BuildRequires: db-devel
@ -204,7 +214,31 @@ Group: Productivity/Networking/LDAP/Clients
%description -n libldap-2_4-2 %description -n libldap-2_4-2
This package contains the OpenLDAP client libraries. This package contains the OpenLDAP client libraries.
%package ppolicy-check-password
Version: %{version_ppolicy_check_module}
Release: 0
Summary: Password quality check module for OpenLDAP
Group: Productivity/Networking/LDAP/Servers
Url: https://github.com/onyxpoint/ppolicy-check-password
BuildRequires: cracklib-devel
Requires: openldap2 = %version_main
Recommends: cracklib cracklib-dict-full
%description ppolicy-check-password
An implementation of password quality check module, based on the original
work done by LDAP Toolbox Project (https://ltd-project.org), that works
together with OpenLDAP password policy overlay (ppolicy), to enforce
password strength policies.
%prep %prep
# Unpack ppolicy check module
%setup -b 200 -q -n %{name_ppolicy_check_module}-%{version_ppolicy_check_module}
%patch200 -p1
cd ..
# Compress the manual page of ppolicy check module
gzip -k %{S:203}
# Unpack and patch OpenLDAP 2.4
%setup -q -n openldap-%{version_main} %setup -q -n openldap-%{version_main}
%patch3 -p1 %patch3 -p1
%patch5 -p1 %patch5 -p1
@ -216,6 +250,10 @@ This package contains the OpenLDAP client libraries.
%patch11 -p1 %patch11 -p1
cp %{SOURCE5} . cp %{SOURCE5} .
# Move ppolicy check module and its Makefile into openldap-2.4/contrib/slapd-modules/
mv ../%{name_ppolicy_check_module}-%{version_ppolicy_check_module} contrib/slapd-modules/%{name_ppolicy_check_module}
cp %{S:201} contrib/slapd-modules/%{name_ppolicy_check_module}/Makefile
%build %build
export CFLAGS="%{optflags} -Wno-format-extra-args -fno-strict-aliasing -DNDEBUG -DSLAP_CONFIG_DELETE -DSLAP_SCHEMA_EXPOSE -DLDAP_COLLECTIVE_ATTRIBUTES" export CFLAGS="%{optflags} -Wno-format-extra-args -fno-strict-aliasing -DNDEBUG -DSLAP_CONFIG_DELETE -DSLAP_SCHEMA_EXPOSE -DLDAP_COLLECTIVE_ATTRIBUTES"
export STRIP="" export STRIP=""
@ -264,6 +302,9 @@ done
# slapo-smbk5pwd only for Samba password hashes # slapo-smbk5pwd only for Samba password hashes
make -C contrib/slapd-modules/smbk5pwd %{?_smp_mflags} "sysconfdir=%{_sysconfdir}/openldap" "libdir=%{_libdir}" "libexecdir=%{_libdir}" DEFS="-DDO_SAMBA" HEIMDAL_LIB="" make -C contrib/slapd-modules/smbk5pwd %{?_smp_mflags} "sysconfdir=%{_sysconfdir}/openldap" "libdir=%{_libdir}" "libexecdir=%{_libdir}" DEFS="-DDO_SAMBA" HEIMDAL_LIB=""
# Build ppolicy-check-password module
make -C contrib/slapd-modules/%{name_ppolicy_check_module} %{?_smp_mflags} "sysconfdir=%{_sysconfdir}/openldap" "libdir=%{_libdir}" "libexecdir=%{_libdir}"
%check %check
%if %run_test_suite %if %run_test_suite
# calculate the base port to be use in the test-suite # calculate the base port to be use in the test-suite
@ -315,6 +356,18 @@ chmod a+x ${RPM_BUILD_ROOT}/%{_libdir}/libldap_r.so*
chmod a+x ${RPM_BUILD_ROOT}/%{_libdir}/libldap.so* chmod a+x ${RPM_BUILD_ROOT}/%{_libdir}/libldap.so*
install -m 755 %{SOURCE6} ${RPM_BUILD_ROOT}/usr/sbin/schema2ldif install -m 755 %{SOURCE6} ${RPM_BUILD_ROOT}/usr/sbin/schema2ldif
# Install ppolicy check module
make -C contrib/slapd-modules/ppolicy-check-password STRIP="" "DESTDIR=${RPM_BUILD_ROOT}" "sysconfdir=%{_sysconfdir}/openldap" "libdir=%{_libdir}" "libexecdir=%{_libexecdir}" install
install -m 0644 %{S:202} %{buildroot}%{_sysconfdir}/openldap/check_password.conf
# Install ppolicy check module's doc files
pushd contrib/slapd-modules/%{name_ppolicy_check_module}
mkdir -p "%{buildroot}%ppolicy_docdir"
install -m 0644 README "%{buildroot}%ppolicy_docdir"
install -m 0644 LICENSE "%{buildroot}%ppolicy_docdir"
popd
# Install ppolicy check module's manual page
install -m 0644 %{S:203}.gz %{buildroot}%{_mandir}/man5/
mkdir -p ${RPM_BUILD_ROOT}/var/adm/fillup-templates mkdir -p ${RPM_BUILD_ROOT}/var/adm/fillup-templates
install -m 644 %{SOURCE16} ${RPM_BUILD_ROOT}/var/adm/fillup-templates/sysconfig.openldap install -m 644 %{SOURCE16} ${RPM_BUILD_ROOT}/var/adm/fillup-templates/sysconfig.openldap
install -m 644 %{SOURCE9} ${RPM_BUILD_ROOT}%{_sysconfdir}/openldap/schema install -m 644 %{SOURCE9} ${RPM_BUILD_ROOT}%{_sysconfdir}/openldap/schema
@ -436,7 +489,8 @@ fi
%{_libdir}/openldap/dynlist* %{_libdir}/openldap/dynlist*
%{_libdir}/openldap/memberof* %{_libdir}/openldap/memberof*
%{_libdir}/openldap/pcache* %{_libdir}/openldap/pcache*
%{_libdir}/openldap/ppolicy* %{_libdir}/openldap/ppolicy-2.4.*
%{_libdir}/openldap/ppolicy.*
%{_libdir}/openldap/refint* %{_libdir}/openldap/refint*
%{_libdir}/openldap/retcode* %{_libdir}/openldap/retcode*
%{_libdir}/openldap/rwm* %{_libdir}/openldap/rwm*
@ -555,4 +609,11 @@ fi
%_libdir/liblber.a %_libdir/liblber.a
%_libdir/libldap*.a %_libdir/libldap*.a
%files ppolicy-check-password
%defattr(-,root,root)
%doc %{ppolicy_docdir}/
%config(noreplace) /etc/openldap/check_password.conf
%{_libdir}/openldap/ppolicy-check-password.*
%{_mandir}/man5/ppolicy-check-password.*
%changelog %changelog

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:840517adc7fa60cb45050ba203437e29458542d9d7f23e906520e0b2fca56fe9
size 10354

182
ppolicy-check-password.5 Normal file
View File

@ -0,0 +1,182 @@
.\"/*
.\" * All rights reserved
.\" * Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
.\" * Authors: Howard Guo <hguo@suse.com>
.\" *
.\" * This program is free software; you can redistribute it and/or
.\" * modify it under the terms of the GNU General Public License
.\" * as published by the Free Software Foundation; either version 2
.\" * of the License, or (at your option) any later version.
.\" *
.\" * This program is distributed in the hope that it will be useful,
.\" * but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.\" * GNU General Public License for more details.
.\" */
.\"
.TH PPOLICY-CHECK-PASSWORD 5 "2016/02/18" "OpenLDAP password quality check"
.SH NAME
ppolicy\-check\-password \- Password quality checker for OpenLDAP ppolicy overlay
.SH SYNOPSIS
pwdCheckModule ppolicy-check-password.so
.SH DESCRIPTION
ppolicy\-check\-password is an implementation of password quality check module, it can be plugged into OpenLDAP
.BR slapo\-ppolicy (5)
overlay to enforce organisational password strength policies for password-change operations.
.SH PREREQUISITES
In order to use the module, you should enable and configure
.BR slapo\-ppolicy (5)
overlay on the OpenLDAP server. You may use the following example to enable ppolicy overlay:
.HP 4
Enable ppolicy overlay
To enable ppolicy overlay on the server using static configuration file
.BR slapd.conf (5)
, first enable ppolicy schema by adding line:
.br
include /etc/openldap/schema/ppolicy.schema
and then append the following lines to the database definition in which password policy should be enforced:
.br
overlay ppolicy
.br
ppolicy_default "cn=PolicyContainer,dc=my-domain,dc=com"
Save slapd.conf and (re)start OpenLDAP server.
If you use cn=config (online configuration) instead of static configuration file, add the schema /etc/openldap/schema/ppolicy.ldif to cn=schema,cn=config, then enable ppolicy overlay in olcDatabase.
.LP
.HP 4
Create ppolicy container entry
The ppolicy container entry stores attributes that describe the password policy in detail, create the entry with
.BR ldapadd (1)
:
.br
dn: cn=PolicyContainer,dc=my-domain,dc=com
.br
cn: PolicyContainer
.br
objectClass: pwdPolicy
.br
objectClass: person
.br
objectClass: top
.br
pwdAllowUserChange: TRUE
.br
pwdAttribute: userPassword
.br
pwdCheckQuality: 2
.br
pwdExpireWarning: 600
.br
pwdFailureCountInterval:
.br
pwdGraceAuthNLimit: 5
.br
pwdInHistory: 5
.br
pwdLockout: TRUE
.br
pwdLockoutDuration: 0
.br
pwdMaxAge: 0
.br
pwdMaxFailure:
.br
pwdMinAge: 0
.br
pwdMinLength: 5
.br
pwdMustChange: FALSE
.br
pwdSafeModify: FALSE
.br
sn: dummy value
.br
The password policy becomes effective immediately, there is no need to restart OpenLDAP server.
.LP
.HP 4
Enable ppolicy-check-password.so module
Modify the ppolicy container entry with
.BR ldapmodify (1)
:
.br
dn: cn=PolicyContainer,dc=my-domain,dc=com
.br
changeType: modify
.br
add: objectClass
.br
objectClass: pwdPolicyChecker
.br
\-
.br
add: pwdCheckModule
.br
pwdCheckModule: ppolicy-check-password.so
The password check module becomes effective immediately, there is no need to restart OpenLDAP server.
.LP
.SH CONFIGURATION
The password check module reads configuration parameters from
.B /etc/openldap/check_password.conf
Edits made to the configuration file become effective immediately, there is no need to restart OpenLDAP server.
List of parameters:
.TP
.BI use_cracklib \ 1|0
CrackLib is a library for checking that a password is not easily crackable, making sure that the password is not based on simple patterns or dictionary words. If the parameter is set to 1, cracklib will be involved and new passwords must pass cracklib quality check in addition to all other policies such as min_points
.TP
.BI min_points \ <integer>
The parameter holds an integer value in between 0 and 4. The value denotes "quality points" that a password must acquire in order to pass the check. Usage of each character class awards one quality point. If the parameeter is set to 0, the check is disabled.
The character classes are: upper case letters, lower case letters, numeric digits, punctuations.
.TP
.BI min_upper \ <integer>
The minimal number of upper case characters a password must contain. If the parameter is set to 0, the check is disabled.
.TP
.BI min_lower \ <integer>
The minimal number of lower case characters a password must contain. If the parameter is set to 0, the check is disabled.
.TP
.BI min_digit \ <integer>
The minimal number of numeric digit characters a password must contain. If the parameter is set to 0, the check is disabled.
.TP
.BI min_punct \ <integer>
The minimal number of punctuation characters a password must contain. If the parameter is set to 0, the check is disabled.
.TP
.BI max_consecutive_per_class \ <integer>
The maximum number of characters from each character class that may appear consecutively. If the parameter is set to 0, the check is disabled.
.SH USAGE
After the module is enabled, the OpenLDAP server will invoke the password checker module on every user password change, the new user password must pass all quality checks before it is accepted. If the new password does not pass quality checks, the detailed reason will be logged on the OpenLDAP server, and the client will receive a Constraint Violation and a generic error message "Password fails quality checking policy" \- the lack of details is by design.
If the password change is carried out by RootDN, password checker module will not enforce the quality checks, and any password is acceptable.
.SH FILES
.TP
/etc/openldap/check_password.conf
Define the password strength policy.
.SH SEE ALSO
.BR slapd.conf (5),
.BR slapd\-config (5),
.BR slapd (8),
.BR slapo\-ppolicy (5)
.SH ACKNOWLEDGEMENTS
.P
The module was originally authored by LTB-project (ltb\-project.org), and further maintained by Onyx Point (onyxpoint.com).

View File

@ -0,0 +1,43 @@
LDAP_SRC = ../../..
LDAP_BUILD = $(LDAP_SRC)
LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
LDAP_LIB = $(LDAP_BUILD)/libraries/libldap_r/libldap_r.la \
$(LDAP_BUILD)/libraries/liblber/liblber.la
LIBTOOL = $(LDAP_BUILD)/libtool
CC = gcc
OPT = -g -O2 -Wall -fpic -DHAVE_CRACKLIB -DCRACKLIB_DICTPATH="\"/usr/share/cracklib/pw_dict\"" -DCONFIG_FILE="\"/etc/openldap/check_password.conf\"" -lcrack
INCS = $(LDAP_INC)
LIBS = $(LDAP_LIB)
PROGRAMS = ppolicy-check-password.la
LTVER = 0:0:0
prefix=/usr/local
exec_prefix=$(prefix)
ldap_subdir=/openldap
libdir=$(exec_prefix)/lib64
libexecdir=$(exec_prefix)/libexec
moduledir=$(libdir)$(ldap_subdir)
.SUFFIXES: .c .o .lo
.c.lo:
$(LIBTOOL) --mode=compile $(CC) $(OPT) $(DEFS) $(INCS) -c $<
all: $(PROGRAMS)
ppolicy-check-password.la: check_password.lo
$(LIBTOOL) --mode=link $(CC) $(OPT) -version-info $(LTVER) \
-rpath $(moduledir) -module -o $@ $? $(LIBS)
clean:
rm -rf *.o *.lo *.la .libs
install: $(PROGRAMS)
mkdir -p $(DESTDIR)$(moduledir)
for p in $(PROGRAMS) ; do \
$(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \
done

View File

@ -0,0 +1,7 @@
use_cracklib 1
min_points 3
min_upper 0
min_lower 0
min_digit 0
min_punct 0
max_consecutive_per_class 5