User-Visible krb5-strength Changes
+krb5-strength 2.1 (2013-10-10)
+
+ Fix the package build when CDB support is disabled or TinyCDB was not
+ found.
+
+ Some of the password rejection error messages have been changed to
+ make them more accurate or comprehensible to the user.
+
+ Passing --with-tinycdb to configure now correctly makes TinyCDB
+ support mandatory without adding bogus directories to the library and
+ include search paths.
+
krb5-strength 2.0 (2013-10-07)
Add support for the MIT Kerberos password quality plugin interface,
- krb5-strength 2.0
+ krb5-strength 2.1
(Kerberos password strength checking plugin)
Maintained by Russ Allbery <rra@stanford.edu>
BLURB
- krb5-strength provides mechanisms for checking the strength of Kerberos
- passwords against an external dictionary when a user changes passwords
- in a Kerberos KDC. It is roughly equivalent to checking password
- strength via CrackLib, except that it embeds a copy of Alec Muffett's
- CrackLib that has been modified to perform slightly more strenuous
- tests. It supports both Heimdal and MIT Kerberos (1.9 or later).
+ krb5-strength provides a password quality plugin for the MIT Kerberos
+ KDC (specifically the kadmind server) and an external password quality
+ program for use with the Heimdal kpasswdd server. Passwords can be
+ tested with CrackLib, checked against a CDB database of known weak
+ passwords, checked for length, checked for non-printable or non-ASCII
+ characters that may be difficult to enter reproducibly, required to
+ contain a non-alphabetic character, or any combination of these tests.
+ It supports both Heimdal and MIT Kerberos (1.9 or later).
DESCRIPTION
bulky, often covered by murky copyrights, and easily locatable on the
Internet with a modicum of searching, none are included in this toolkit.
+ To run the test suite, you will also need Perl 5.006 or later. The
+ following additional Perl modules will be used by the test suite if
+ present:
+
+ File::Slurp
+ IPC::Run
+ JSON
+ Test::MinimumVersion
+ Test::Perl::Critic
+ Test::Pod
+ Test::Spelling
+ Test::Strict
+
+ All are available on CPAN. Those tests will be skipped if the modules
+ are not available.
+
+ To enable tests that may be sensitive to the local environment or that
+ produce a lot of false positives without uncovering many problems, set
+ RRA_MAINTAINER_TESTS to a true value.
+
To bootstrap from a Git checkout, or If you change the Automake files
and need to regenerate Makefile.in, you will need Automake 1.11 or
later. For bootstrap or if you change configure.ac or any of the m4
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for krb5-strength 2.0.
+# Generated by GNU Autoconf 2.69 for krb5-strength 2.1.
#
# Report bugs to <rra@stanford.edu>.
#
# Identity of this package.
PACKAGE_NAME='krb5-strength'
PACKAGE_TARNAME='krb5-strength'
-PACKAGE_VERSION='2.0'
-PACKAGE_STRING='krb5-strength 2.0'
+PACKAGE_VERSION='2.1'
+PACKAGE_STRING='krb5-strength 2.1'
PACKAGE_BUGREPORT='rra@stanford.edu'
PACKAGE_URL=''
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures krb5-strength 2.0 to adapt to many kinds of systems.
+\`configure' configures krb5-strength 2.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of krb5-strength 2.0:";;
+ short | recursive ) echo "Configuration of krb5-strength 2.1:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-krb5-strength configure 2.0
+krb5-strength configure 2.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by krb5-strength $as_me 2.0, which was
+It was created by krb5-strength $as_me 2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='krb5-strength'
- VERSION='2.0'
+ VERSION='2.1'
cat >>confdefs.h <<_ACEOF
withval=$with_tinycdb; if test x"$withval" = xno; then :
rra_use_CDB=false
else
- if test x"$withval" != yes; then :
+ if test x"$withval" != xyes; then :
rra_CDB_root="$withval"
fi
rra_use_CDB=true
$as_echo "$ac_cv_lib_cdb_cdb_init" >&6; }
if test "x$ac_cv_lib_cdb_cdb_init" = xyes; then :
CDB_LIBS=-lcdb
+
+$as_echo "#define HAVE_CDB 1" >>confdefs.h
+
+ rra_use_CDB=true
else
if test x"true" = xtrue; then :
as_fn_error $? "cannot find usable TinyCDB library" "$LINENO" 5
$as_echo "$ac_cv_lib_cdb_cdb_init" >&6; }
if test "x$ac_cv_lib_cdb_cdb_init" = xyes; then :
CDB_LIBS=-lcdb
+
+$as_echo "#define HAVE_CDB 1" >>confdefs.h
+
+ rra_use_CDB=true
else
if test x"false" = xtrue; then :
as_fn_error $? "cannot find usable TinyCDB library" "$LINENO" 5
LDFLAGS="$rra_CDB_save_LDFLAGS"
LIBS="$rra_CDB_save_LIBS"
fi
-fi
- if test x"$CDB_LIBS" != x; then :
-
-$as_echo "#define HAVE_CDB 1" >>confdefs.h
-
fi
rra_system_cracklib=
rra_cracklib_root=
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by krb5-strength $as_me 2.0, which was
+This file was extended by krb5-strength $as_me 2.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-krb5-strength config.status 2.0
+krb5-strength config.status 2.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
dnl Basic Autoconf configuration.
AC_PREREQ([2.64])
-AC_INIT([krb5-strength], [2.0], [rra@stanford.edu])
+AC_INIT([krb5-strength], [2.1], [rra@stanford.edu])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_LIBOBJ_DIR([portable])
AC_CONFIG_MACRO_DIR([m4])
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2011
+dnl Copyright 2011, 2013
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl This file is free software; the authors give unlimited permission to copy
[Location of $2 headers and libraries])],
[AS_IF([test x"$withval" = xno],
[rra_use_$3=false],
- [AS_IF([test x"$withval" != yes], [rra_$3[]_root="$withval"])
+ [AS_IF([test x"$withval" != xyes], [rra_$3[]_root="$withval"])
rra_use_$3=true])])
AC_ARG_WITH([$1][-include],
[AS_HELP_STRING([--with-][$1][-include=DIR],
dnl provides RRA_LIB_CDB_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include
dnl the kadmin client libraries, saving the ecurrent values, and
dnl RRA_LIB_CDB_RESTORE to restore those settings to before the last
-dnl RRA_LIB_CDB_SWITCH. Define HAVE_CDB if the library is found.
+dnl RRA_LIB_CDB_SWITCH. Defines HAVE_CDB and sets rra_use_CDB to true if the
+dnl library is found.
dnl
-dnl Depends on RRA_SET_LDFLAGS.
+dnl Depends on the lib-helper.m4 infrastructure.
dnl
dnl Written by Russ Allbery <rra@stanford.edu>
dnl Copyright 2010, 2013
AC_DEFUN([_RRA_LIB_CDB_INTERNAL],
[RRA_LIB_HELPER_PATHS([CDB])
RRA_LIB_CDB_SWITCH
- AC_CHECK_LIB([cdb], [cdb_init], [CDB_LIBS=-lcdb],
+ AC_CHECK_LIB([cdb], [cdb_init],
+ [CDB_LIBS=-lcdb
+ AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])
+ rra_use_CDB=true],
[AS_IF([test x"$1" = xtrue],
[AC_MSG_ERROR([cannot find usable TinyCDB library])])])
AC_CHECK_HEADERS([cdb.h])
AC_DEFUN([RRA_LIB_CDB],
[RRA_LIB_HELPER_VAR_INIT([CDB])
RRA_LIB_HELPER_WITH([tinycdb], [TinyCDB], [CDB])
- _RRA_LIB_CDB_INTERNAL([true])
- AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])])
+ _RRA_LIB_CDB_INTERNAL([true])])
dnl The main macro for packages with optional kadmin client support.
AC_DEFUN([RRA_LIB_CDB_OPTIONAL],
AS_IF([test x"$rra_use_CDB" != xfalse],
[AS_IF([test x"$rra_use_CDB" = xtrue],
[_RRA_LIB_CDB_INTERNAL([true])],
- [_RRA_LIB_CDB_INTERNAL([false])])])
- AS_IF([test x"$CDB_LIBS" != x],
- [AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])])])
+ [_RRA_LIB_CDB_INTERNAL([false])])])])
* Stub for strength_init_cdb if not built with CDB support.
*/
#ifndef HAVE_CDB
-static krb5_error_code
-strength_init_cdb(krb5_context ctx, krb5_pwqual_moddata data UNUSED,
- const char *database UNUSED)
+krb5_error_code
+strength_init_cdb(krb5_context ctx, krb5_pwqual_moddata data UNUSED)
{
char *path = NULL;
/* Error strings returned (and displayed to the user) for various failures. */
#define ERROR_ASCII "password contains non-ASCII or control characters"
-#define ERROR_DICT "password is based on a dictionary word"
+#define ERROR_DICT "password found in list of common passwords"
#define ERROR_LETTER "password is only letters and spaces"
#define ERROR_SHORT "password is too short"
-#define ERROR_USERNAME "password based on username"
+#define ERROR_USERNAME "password based on username or principal"
/*
* MIT Kerberos uses this type as an abstract data type for any data that a
krb5_error_code strength_check(krb5_context, krb5_pwqual_moddata,
const char *principal, const char *password);
-/* Free the subset of internal data used by the CDB dictionary checks. */
-void strength_close_cdb(krb5_context, krb5_pwqual_moddata);
+/* Free the internal plugin state. */
+void strength_close(krb5_context, krb5_pwqual_moddata);
/*
* CDB handling. strength_init_cdb gets the dictionary configuration and sets
#ifdef HAVE_CDB
krb5_error_code strength_check_cdb(krb5_context, krb5_pwqual_moddata,
const char *password);
-void strength_close(krb5_context, krb5_pwqual_moddata);
+void strength_close_cdb(krb5_context, krb5_pwqual_moddata);
#else
# define strength_check_cdb(c, d, p) 0
# define strength_close_cdb(c, d) /* empty */
"test@EXAMPLE.ORG",
"password",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"test@EXAMPLE.ORG",
"bitterbane",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"test@EXAMPLE.ORG",
"1bitterbane",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"test@EXAMPLE.ORG",
"bitterbane1",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"test@EXAMPLE.ORG",
"abbitterbane",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"test@EXAMPLE.ORG",
"bitterbane12",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"test@EXAMPLE.ORG",
"'bitterbane'",
KADM5_PASS_Q_DICT,
- "password is based on a dictionary word",
+ "password found in list of common passwords",
},
{
"principal": "test@EXAMPLE.ORG",
"password": "password",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "in dictionary (longer)",
"principal": "test@EXAMPLE.ORG",
"password": "bitterbane",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "in dictionary (drop first)",
"principal": "test@EXAMPLE.ORG",
"password": "1bitterbane",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "in dictionary (drop last)",
"principal": "test@EXAMPLE.ORG",
"password": "bitterbane1",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "in dictionary (drop first two)",
"principal": "test@EXAMPLE.ORG",
"password": "abbitterbane",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "in dictionary (drop last two)",
"principal": "test@EXAMPLE.ORG",
"password": "bitterbane12",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "in dictionary (drop first and last)",
"principal": "test@EXAMPLE.ORG",
"password": "'bitterbane'",
"code": "KADM5_PASS_Q_DICT",
- "error": "password is based on a dictionary word"
+ "error": "password found in list of common passwords"
},
{
"name": "dictionary with three characters",
"someuser@EXAMPLE.ORG",
"someuser",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@EXAMPLE.ORG",
"resuemos",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@EXAMPLE.ORG",
"someuser123",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"test@EXAMPLE.ORG",
"test@EXAMPLE.ORG",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@EXAMPLE.ORG",
"123someuser",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@EXAMPLE.ORG",
"1someuser2",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@NEWEXAMPLE.ORG",
"newexample",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@NEWEXAMPLE.ORG",
"newexample123",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@NEWEXAMPLE.ORG",
"123newexample",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@NEWEXAMPLE.ORG",
"ELPMAXEWEN",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@NEWEXAMPLE.ORG",
"ORG1791520",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
{
"someuser@NEWEXAMPLE.ORG",
"NewExample.Org",
KADM5_PASS_Q_GENERIC,
- "password based on username",
+ "password based on username or principal",
},
};
"principal": "someuser@EXAMPLE.ORG",
"password": "someuser",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "based on principal (reversed)",
"principal": "someuser@EXAMPLE.ORG",
"password": "resuemos",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "based on principal with digits",
"principal": "someuser@EXAMPLE.ORG",
"password": "someuser123",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is full principal",
"principal": "test@EXAMPLE.ORG",
"password": "test@EXAMPLE.ORG",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "principal with leading digits",
"principal": "someuser@EXAMPLE.ORG",
"password": "123someuser",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "principal with leading and trailing digits",
"principal": "someuser@EXAMPLE.ORG",
"password": "1someuser2",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is realm (lowercase)",
"principal": "someuser@NEWEXAMPLE.ORG",
"password": "newexample",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is realm (lowercase) with digits",
"principal": "someuser@NEWEXAMPLE.ORG",
"password": "newexample123",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is realm (lowercase) with leading digits",
"principal": "someuser@NEWEXAMPLE.ORG",
"password": "123newexample",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is realm reversed",
"principal": "someuser@NEWEXAMPLE.ORG",
"password": "ELPMAXEWEN",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is second realm with digits",
"principal": "someuser@NEWEXAMPLE.ORG",
"password": "ORG1791520",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
},
{
"name": "is whole realm (mixed case)",
"principal": "someuser@NEWEXAMPLE.ORG",
"password": "NewExample.Org",
"code": "KADM5_PASS_Q_GENERIC",
- "error": "password based on username"
+ "error": "password based on username or principal"
}
]
.\" ========================================================================
.\"
.IX Title "CDBMAKE-WORDLIST 1"
-.TH CDBMAKE-WORDLIST 1 "2013-10-07" "2.0" "krb5-strength"
+.TH CDBMAKE-WORDLIST 1 "2013-10-10" "2.1" "krb5-strength"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.\" ========================================================================
.\"
.IX Title "HEIMDAL-STRENGTH 1"
-.TH HEIMDAL-STRENGTH 1 "2013-10-07" "2.0" "krb5-strength"
+.TH HEIMDAL-STRENGTH 1 "2013-10-10" "2.1" "krb5-strength"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l