/tests/plugin/mit-t
/tests/portable/asprintf-t
/tests/portable/snprintf-t
+/tests/portable/strndup-t
/tests/runtests
/tests/tap/libtap.a
/tests/util/messages-krb5-t
License: Expat
Files: *
-Copyright: 2000-2002, 2004-2012 Russ Allbery <rra@stanford.edu>
+Copyright: 2000-2002, 2004-2013 Russ Allbery <eagle@eyrie.org>
2001-2002, 2004-2013
The Board of Trustees of the Leland Stanford Junior University
- 2006-2007, 2009, 2012-2013
- The Board of Trustees of the Leland Stanford Junior Unversity
2010 the Massachusetts Institute of Technology
License: Expat
Files: portable/asprintf.c portable/dummy.c portable/kadmin.h
portable/krb5-extra.c portable/krb5.h portable/macros.h portable/stdbool.h
- portable/system.h tests/portable/asprintf-t.c util/macros.h
+ portable/strndup.c portable/system.h tests/portable/asprintf-t.c
+ tests/portable/strndup-t.c util/macros.h
Copyright: no copyright notice, see License
License: rra-public-domain
The authors hereby relinquish any claim to any copyright that they may
Files: portable/snprintf.c tests/portable/snprintf-t.c
Copyright: 1995 Patrick Powell
- 2000-2006 Russ Allbery <rra@stanford.edu>
+ 2000-2006 Russ Allbery <eagle@eyrie.org>
2001 Hrvoje Niksic
2009-2010 The Board of Trustees of the Leland Stanford Junior University
License: Powell-snprintf
on all source code distributions
Files: tests/HOWTO tools/heimdal-strength.1 tools/heimdal-strength.pod
-Copyright: 2010 Russ Allbery <rra@stanford.edu>
+Copyright: 2010 Russ Allbery <eagle@eyrie.org>
2010, 2013 The Board of Trustees of the Leland Stanford Junior University
License: all-permissive
Copying and distribution of this file, with or without modification, are
# Automake makefile for krb5-strength.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2007, 2009, 2010, 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
cracklib/README cracklib/genrules.pl cracklib/mkdict tests/HOWTO \
tests/TESTS tests/data/krb5.conf tests/data/make-krb5-conf \
tests/data/passwords tests/data/perl.conf tests/data/perlcriticrc \
- tests/data/perltidyrc tests/data/wordlist tests/data/wordlist.cdb \
- tests/docs/pod-spelling-t tests/docs/pod-t tests/perl/critic-t \
- tests/perl/minimum-version-t tests/perl/strict-t \
- tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm \
+ tests/data/perltidyrc tests/data/valgrind.supp tests/data/wordlist \
+ tests/data/wordlist.cdb tests/docs/pod-spelling-t tests/docs/pod-t \
+ tests/perl/critic-t tests/perl/minimum-version-t \
+ tests/perl/strict-t tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm \
tests/tap/perl/Test/RRA/Config.pm \
tests/tap/perl/Test/RRA/Automake.pm tests/tools/cdbmake-wordlist-t \
tests/tools/heimdal-strength-t tests/util/xmalloc-t \
# Rules for building the password strength plugin.
module_LTLIBRARIES = plugin/strength.la
-plugin_strength_la_SOURCES = plugin/cdb.c plugin/config.c plugin/cracklib.c \
- plugin/error.c plugin/general.c plugin/heimdal.c plugin/internal.h \
- plugin/mit.c plugin/principal.c
+plugin_strength_la_SOURCES = plugin/cdb.c plugin/classes.c plugin/config.c \
+ plugin/cracklib.c plugin/error.c plugin/general.c plugin/heimdal.c \
+ plugin/internal.h plugin/mit.c plugin/principal.c plugin/vector.c
plugin_strength_la_LDFLAGS = -module -avoid-version
if EMBEDDED_CRACKLIB
plugin_strength_la_LIBADD = cracklib/libcracklib.la
# The Heimdal external check program.
bin_PROGRAMS = tools/heimdal-strength
tools_heimdal_strength_CFLAGS = $(AM_CFLAGS)
-tools_heimdal_strength_SOURCES = plugin/cdb.c plugin/config.c \
- plugin/cracklib.c plugin/error.c plugin/general.c plugin/internal.h \
- plugin/principal.c tools/heimdal-strength.c
+tools_heimdal_strength_SOURCES = plugin/cdb.c plugin/classes.c \
+ plugin/config.c plugin/cracklib.c plugin/error.c plugin/general.c \
+ plugin/internal.h plugin/principal.c plugin/vector.c \
+ tools/heimdal-strength.c
if EMBEDDED_CRACKLIB
tools_heimdal_strength_LDADD = cracklib/libcracklib.la
else
$(MAKE) V=0 CFLAGS='$(WARNINGS)' $(check_PROGRAMS)
# The bits below are for the test suite, not for the main package.
-check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \
- tests/portable/asprintf-t tests/portable/snprintf-t \
- tests/util/messages-krb5-t tests/util/messages-t tests/util/xmalloc
+check_PROGRAMS = tests/runtests tests/plugin/heimdal-t tests/plugin/mit-t \
+ tests/portable/asprintf-t tests/portable/snprintf-t \
+ tests/portable/strndup-t tests/util/messages-krb5-t \
+ tests/util/messages-t tests/util/xmalloc
if EMBEDDED_CRACKLIB
check_PROGRAMS += cracklib/packer
endif
tests_portable_snprintf_t_SOURCES = tests/portable/snprintf-t.c \
tests/portable/snprintf.c
tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la
+tests_portable_strndup_t_SOURCES = tests/portable/strndup-t.c \
+ tests/portable/strndup.c
+tests_portable_strndup_t_LDADD = tests/tap/libtap.a portable/libportable.la
tests_util_messages_t_LDADD = tests/tap/libtap.a util/libutil.a \
portable/libportable.la
tests_util_messages_krb5_t_LDADD = tests/tap/libtap.a util/libutil.a \
check-local: $(check_PROGRAMS) tests/data/dictionary.pwd
cd tests && ./runtests -l $(abs_top_srcdir)/tests/TESTS
+
+# Used by maintainers to run the main test suite under valgrind. Suppress
+# the xmalloc and pod-spelling tests because the former won't work properly
+# under valgrind (due to increased memory usage) and the latter is pointless
+# to run under valgrind. Don't try to trace the test for cdbmake-wordlist,
+# since it's pure Perl.
+check-valgrind: $(check_PROGRAMS) tests/data/dictionary.pwd
+ rm -rf $(abs_top_builddir)/tmp-valgrind
+ mkdir $(abs_top_builddir)/tmp-valgrind
+ env RRA_MAINTAINER_TESTS= valgrind --leak-check=full \
+ --show-reachable=yes --trace-children=yes \
+ --log-file=$(abs_top_builddir)/tmp-valgrind/log.%p \
+ --suppressions=tests/data/valgrind.supp \
+ --trace-children-skip="/bin/sh,*/cat,*/diff,*/expr,*/grep,*/mkdir,*/rm,*/rmdir,*/sed,*/sleep,*/true,*/wc,*/docs/*-t,*/perl/*-t,*/data/make-krb5-conf,*/tools/cdbmake-wordlist-t" \
+ tests/runtests -l '$(abs_top_srcdir)/tests/TESTS'
# Automake makefile for krb5-strength.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2007, 2009, 2010, 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
tests/plugin/heimdal-t$(EXEEXT) tests/plugin/mit-t$(EXEEXT) \
tests/portable/asprintf-t$(EXEEXT) \
tests/portable/snprintf-t$(EXEEXT) \
+ tests/portable/strndup-t$(EXEEXT) \
tests/util/messages-krb5-t$(EXEEXT) \
tests/util/messages-t$(EXEEXT) tests/util/xmalloc$(EXEEXT) \
$(am__EXEEXT_1)
subdir = .
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
- $(srcdir)/config.h.in $(top_srcdir)/portable/asprintf.c \
- $(top_srcdir)/portable/krb5-extra.c \
- $(top_srcdir)/portable/snprintf.c $(dist_bin_SCRIPTS) \
+ $(srcdir)/config.h.in $(top_srcdir)/portable/snprintf.c \
+ $(top_srcdir)/portable/asprintf.c \
+ $(top_srcdir)/portable/strndup.c \
+ $(top_srcdir)/portable/krb5-extra.c $(dist_bin_SCRIPTS) \
$(top_srcdir)/build-aux/depcomp $(dist_man_MANS) NEWS README \
TODO build-aux/ar-lib build-aux/compile build-aux/config.guess \
build-aux/config.sub build-aux/depcomp build-aux/install-sh \
@EMBEDDED_CRACKLIB_TRUE@ portable/libportable.la \
@EMBEDDED_CRACKLIB_TRUE@ $(am__DEPENDENCIES_1) \
@EMBEDDED_CRACKLIB_TRUE@ $(am__DEPENDENCIES_1)
-am_plugin_strength_la_OBJECTS = plugin/cdb.lo plugin/config.lo \
- plugin/cracklib.lo plugin/error.lo plugin/general.lo \
- plugin/heimdal.lo plugin/mit.lo plugin/principal.lo
+am_plugin_strength_la_OBJECTS = plugin/cdb.lo plugin/classes.lo \
+ plugin/config.lo plugin/cracklib.lo plugin/error.lo \
+ plugin/general.lo plugin/heimdal.lo plugin/mit.lo \
+ plugin/principal.lo plugin/vector.lo
plugin_strength_la_OBJECTS = $(am_plugin_strength_la_OBJECTS)
plugin_strength_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(am_tests_portable_snprintf_t_OBJECTS)
tests_portable_snprintf_t_DEPENDENCIES = tests/tap/libtap.a \
portable/libportable.la
+am_tests_portable_strndup_t_OBJECTS = \
+ tests/portable/strndup-t.$(OBJEXT) \
+ tests/portable/strndup.$(OBJEXT)
+tests_portable_strndup_t_OBJECTS = \
+ $(am_tests_portable_strndup_t_OBJECTS)
+tests_portable_strndup_t_DEPENDENCIES = tests/tap/libtap.a \
+ portable/libportable.la
tests_runtests_SOURCES = tests/runtests.c
tests_runtests_OBJECTS = tests/tests_runtests-runtests.$(OBJEXT)
tests_runtests_LDADD = $(LDADD)
portable/libportable.la
am_tools_heimdal_strength_OBJECTS = \
plugin/tools_heimdal_strength-cdb.$(OBJEXT) \
+ plugin/tools_heimdal_strength-classes.$(OBJEXT) \
plugin/tools_heimdal_strength-config.$(OBJEXT) \
plugin/tools_heimdal_strength-cracklib.$(OBJEXT) \
plugin/tools_heimdal_strength-error.$(OBJEXT) \
plugin/tools_heimdal_strength-general.$(OBJEXT) \
plugin/tools_heimdal_strength-principal.$(OBJEXT) \
+ plugin/tools_heimdal_strength-vector.$(OBJEXT) \
tools/tools_heimdal_strength-heimdal-strength.$(OBJEXT)
tools_heimdal_strength_OBJECTS = $(am_tools_heimdal_strength_OBJECTS)
@EMBEDDED_CRACKLIB_FALSE@tools_heimdal_strength_DEPENDENCIES = \
$(portable_libportable_la_SOURCES) $(cracklib_packer_SOURCES) \
tests/plugin/heimdal-t.c tests/plugin/mit-t.c \
$(tests_portable_asprintf_t_SOURCES) \
- $(tests_portable_snprintf_t_SOURCES) tests/runtests.c \
+ $(tests_portable_snprintf_t_SOURCES) \
+ $(tests_portable_strndup_t_SOURCES) tests/runtests.c \
tests/util/messages-krb5-t.c tests/util/messages-t.c \
tests/util/xmalloc.c $(tools_heimdal_strength_SOURCES)
DIST_SOURCES = $(tests_tap_libtap_a_SOURCES) $(util_libutil_a_SOURCES) \
$(portable_libportable_la_SOURCES) $(cracklib_packer_SOURCES) \
tests/plugin/heimdal-t.c tests/plugin/mit-t.c \
$(tests_portable_asprintf_t_SOURCES) \
- $(tests_portable_snprintf_t_SOURCES) tests/runtests.c \
+ $(tests_portable_snprintf_t_SOURCES) \
+ $(tests_portable_strndup_t_SOURCES) tests/runtests.c \
tests/util/messages-krb5-t.c tests/util/messages-t.c \
tests/util/xmalloc.c $(tools_heimdal_strength_SOURCES)
am__can_run_installinfo = \
cracklib/README cracklib/genrules.pl cracklib/mkdict tests/HOWTO \
tests/TESTS tests/data/krb5.conf tests/data/make-krb5-conf \
tests/data/passwords tests/data/perl.conf tests/data/perlcriticrc \
- tests/data/perltidyrc tests/data/wordlist tests/data/wordlist.cdb \
- tests/docs/pod-spelling-t tests/docs/pod-t tests/perl/critic-t \
- tests/perl/minimum-version-t tests/perl/strict-t \
- tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm \
+ tests/data/perltidyrc tests/data/valgrind.supp tests/data/wordlist \
+ tests/data/wordlist.cdb tests/docs/pod-spelling-t tests/docs/pod-t \
+ tests/perl/critic-t tests/perl/minimum-version-t \
+ tests/perl/strict-t tests/tap/libtap.sh tests/tap/perl/Test/RRA.pm \
tests/tap/perl/Test/RRA/Config.pm \
tests/tap/perl/Test/RRA/Automake.pm tests/tools/cdbmake-wordlist-t \
tests/tools/heimdal-strength-t tests/util/xmalloc-t \
# Rules for building the password strength plugin.
module_LTLIBRARIES = plugin/strength.la
-plugin_strength_la_SOURCES = plugin/cdb.c plugin/config.c plugin/cracklib.c \
- plugin/error.c plugin/general.c plugin/heimdal.c plugin/internal.h \
- plugin/mit.c plugin/principal.c
+plugin_strength_la_SOURCES = plugin/cdb.c plugin/classes.c plugin/config.c \
+ plugin/cracklib.c plugin/error.c plugin/general.c plugin/heimdal.c \
+ plugin/internal.h plugin/mit.c plugin/principal.c plugin/vector.c
plugin_strength_la_LDFLAGS = -module -avoid-version
@EMBEDDED_CRACKLIB_FALSE@plugin_strength_la_LIBADD = $(CRACKLIB_LIBS) \
@EMBEDDED_CRACKLIB_TRUE@ portable/libportable.la $(KRB5_LIBS) \
@EMBEDDED_CRACKLIB_TRUE@ $(CDB_LIBS)
tools_heimdal_strength_CFLAGS = $(AM_CFLAGS)
-tools_heimdal_strength_SOURCES = plugin/cdb.c plugin/config.c \
- plugin/cracklib.c plugin/error.c plugin/general.c plugin/internal.h \
- plugin/principal.c tools/heimdal-strength.c
+tools_heimdal_strength_SOURCES = plugin/cdb.c plugin/classes.c \
+ plugin/config.c plugin/cracklib.c plugin/error.c plugin/general.c \
+ plugin/internal.h plugin/principal.c plugin/vector.c \
+ tools/heimdal-strength.c
@EMBEDDED_CRACKLIB_FALSE@tools_heimdal_strength_LDADD = \
@EMBEDDED_CRACKLIB_FALSE@ $(CRACKLIB_LIBS) util/libutil.a \
tests/portable/snprintf.c
tests_portable_snprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la
+tests_portable_strndup_t_SOURCES = tests/portable/strndup-t.c \
+ tests/portable/strndup.c
+
+tests_portable_strndup_t_LDADD = tests/tap/libtap.a portable/libportable.la
tests_util_messages_t_LDADD = tests/tap/libtap.a util/libutil.a \
portable/libportable.la
@$(MKDIR_P) plugin/$(DEPDIR)
@: > plugin/$(DEPDIR)/$(am__dirstamp)
plugin/cdb.lo: plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
+plugin/classes.lo: plugin/$(am__dirstamp) \
+ plugin/$(DEPDIR)/$(am__dirstamp)
plugin/config.lo: plugin/$(am__dirstamp) \
plugin/$(DEPDIR)/$(am__dirstamp)
plugin/cracklib.lo: plugin/$(am__dirstamp) \
plugin/mit.lo: plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
plugin/principal.lo: plugin/$(am__dirstamp) \
plugin/$(DEPDIR)/$(am__dirstamp)
+plugin/vector.lo: plugin/$(am__dirstamp) \
+ plugin/$(DEPDIR)/$(am__dirstamp)
plugin/strength.la: $(plugin_strength_la_OBJECTS) $(plugin_strength_la_DEPENDENCIES) $(EXTRA_plugin_strength_la_DEPENDENCIES) plugin/$(am__dirstamp)
$(AM_V_CCLD)$(plugin_strength_la_LINK) -rpath $(moduledir) $(plugin_strength_la_OBJECTS) $(plugin_strength_la_LIBADD) $(LIBS)
tests/portable/snprintf-t$(EXEEXT): $(tests_portable_snprintf_t_OBJECTS) $(tests_portable_snprintf_t_DEPENDENCIES) $(EXTRA_tests_portable_snprintf_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
@rm -f tests/portable/snprintf-t$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tests_portable_snprintf_t_OBJECTS) $(tests_portable_snprintf_t_LDADD) $(LIBS)
+tests/portable/strndup-t.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+tests/portable/strndup.$(OBJEXT): tests/portable/$(am__dirstamp) \
+ tests/portable/$(DEPDIR)/$(am__dirstamp)
+
+tests/portable/strndup-t$(EXEEXT): $(tests_portable_strndup_t_OBJECTS) $(tests_portable_strndup_t_DEPENDENCIES) $(EXTRA_tests_portable_strndup_t_DEPENDENCIES) tests/portable/$(am__dirstamp)
+ @rm -f tests/portable/strndup-t$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tests_portable_strndup_t_OBJECTS) $(tests_portable_strndup_t_LDADD) $(LIBS)
tests/$(am__dirstamp):
@$(MKDIR_P) tests
@: > tests/$(am__dirstamp)
$(AM_V_CCLD)$(LINK) $(tests_util_xmalloc_OBJECTS) $(tests_util_xmalloc_LDADD) $(LIBS)
plugin/tools_heimdal_strength-cdb.$(OBJEXT): plugin/$(am__dirstamp) \
plugin/$(DEPDIR)/$(am__dirstamp)
+plugin/tools_heimdal_strength-classes.$(OBJEXT): \
+ plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
plugin/tools_heimdal_strength-config.$(OBJEXT): \
plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
plugin/tools_heimdal_strength-cracklib.$(OBJEXT): \
plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
plugin/tools_heimdal_strength-principal.$(OBJEXT): \
plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
+plugin/tools_heimdal_strength-vector.$(OBJEXT): \
+ plugin/$(am__dirstamp) plugin/$(DEPDIR)/$(am__dirstamp)
tools/$(am__dirstamp):
@$(MKDIR_P) tools
@: > tools/$(am__dirstamp)
@AMDEP_TRUE@@am__include@ @am__quote@cracklib/$(DEPDIR)/cracklib_libcracklib_la-stringlib.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@cracklib/$(DEPDIR)/packer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/cdb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/classes.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/config.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/cracklib.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/mit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/principal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-cdb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-classes.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-config.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-cracklib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-error.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-general.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-principal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/tools_heimdal_strength-vector.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@plugin/$(DEPDIR)/vector.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/asprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/dummy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/krb5-extra.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/snprintf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@portable/$(DEPDIR)/strndup.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/tests_runtests-runtests.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/plugin/$(DEPDIR)/tests_plugin_heimdal_t-heimdal-t.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/plugin/$(DEPDIR)/tests_plugin_mit_t-mit-t.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/asprintf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/snprintf-t.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/snprintf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/strndup-t.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@tests/portable/$(DEPDIR)/strndup.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-basic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-kerberos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@tests/tap/$(DEPDIR)/tests_tap_libtap_a-process.Po@am__quote@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -c -o plugin/tools_heimdal_strength-cdb.obj `if test -f 'plugin/cdb.c'; then $(CYGPATH_W) 'plugin/cdb.c'; else $(CYGPATH_W) '$(srcdir)/plugin/cdb.c'; fi`
+plugin/tools_heimdal_strength-classes.o: plugin/classes.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -MT plugin/tools_heimdal_strength-classes.o -MD -MP -MF plugin/$(DEPDIR)/tools_heimdal_strength-classes.Tpo -c -o plugin/tools_heimdal_strength-classes.o `test -f 'plugin/classes.c' || echo '$(srcdir)/'`plugin/classes.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) plugin/$(DEPDIR)/tools_heimdal_strength-classes.Tpo plugin/$(DEPDIR)/tools_heimdal_strength-classes.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/classes.c' object='plugin/tools_heimdal_strength-classes.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -c -o plugin/tools_heimdal_strength-classes.o `test -f 'plugin/classes.c' || echo '$(srcdir)/'`plugin/classes.c
+
+plugin/tools_heimdal_strength-classes.obj: plugin/classes.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -MT plugin/tools_heimdal_strength-classes.obj -MD -MP -MF plugin/$(DEPDIR)/tools_heimdal_strength-classes.Tpo -c -o plugin/tools_heimdal_strength-classes.obj `if test -f 'plugin/classes.c'; then $(CYGPATH_W) 'plugin/classes.c'; else $(CYGPATH_W) '$(srcdir)/plugin/classes.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) plugin/$(DEPDIR)/tools_heimdal_strength-classes.Tpo plugin/$(DEPDIR)/tools_heimdal_strength-classes.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/classes.c' object='plugin/tools_heimdal_strength-classes.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -c -o plugin/tools_heimdal_strength-classes.obj `if test -f 'plugin/classes.c'; then $(CYGPATH_W) 'plugin/classes.c'; else $(CYGPATH_W) '$(srcdir)/plugin/classes.c'; fi`
+
plugin/tools_heimdal_strength-config.o: plugin/config.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -MT plugin/tools_heimdal_strength-config.o -MD -MP -MF plugin/$(DEPDIR)/tools_heimdal_strength-config.Tpo -c -o plugin/tools_heimdal_strength-config.o `test -f 'plugin/config.c' || echo '$(srcdir)/'`plugin/config.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) plugin/$(DEPDIR)/tools_heimdal_strength-config.Tpo plugin/$(DEPDIR)/tools_heimdal_strength-config.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -c -o plugin/tools_heimdal_strength-principal.obj `if test -f 'plugin/principal.c'; then $(CYGPATH_W) 'plugin/principal.c'; else $(CYGPATH_W) '$(srcdir)/plugin/principal.c'; fi`
+plugin/tools_heimdal_strength-vector.o: plugin/vector.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -MT plugin/tools_heimdal_strength-vector.o -MD -MP -MF plugin/$(DEPDIR)/tools_heimdal_strength-vector.Tpo -c -o plugin/tools_heimdal_strength-vector.o `test -f 'plugin/vector.c' || echo '$(srcdir)/'`plugin/vector.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) plugin/$(DEPDIR)/tools_heimdal_strength-vector.Tpo plugin/$(DEPDIR)/tools_heimdal_strength-vector.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/vector.c' object='plugin/tools_heimdal_strength-vector.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -c -o plugin/tools_heimdal_strength-vector.o `test -f 'plugin/vector.c' || echo '$(srcdir)/'`plugin/vector.c
+
+plugin/tools_heimdal_strength-vector.obj: plugin/vector.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -MT plugin/tools_heimdal_strength-vector.obj -MD -MP -MF plugin/$(DEPDIR)/tools_heimdal_strength-vector.Tpo -c -o plugin/tools_heimdal_strength-vector.obj `if test -f 'plugin/vector.c'; then $(CYGPATH_W) 'plugin/vector.c'; else $(CYGPATH_W) '$(srcdir)/plugin/vector.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) plugin/$(DEPDIR)/tools_heimdal_strength-vector.Tpo plugin/$(DEPDIR)/tools_heimdal_strength-vector.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='plugin/vector.c' object='plugin/tools_heimdal_strength-vector.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -c -o plugin/tools_heimdal_strength-vector.obj `if test -f 'plugin/vector.c'; then $(CYGPATH_W) 'plugin/vector.c'; else $(CYGPATH_W) '$(srcdir)/plugin/vector.c'; fi`
+
tools/tools_heimdal_strength-heimdal-strength.o: tools/heimdal-strength.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tools_heimdal_strength_CFLAGS) $(CFLAGS) -MT tools/tools_heimdal_strength-heimdal-strength.o -MD -MP -MF tools/$(DEPDIR)/tools_heimdal_strength-heimdal-strength.Tpo -c -o tools/tools_heimdal_strength-heimdal-strength.o `test -f 'tools/heimdal-strength.c' || echo '$(srcdir)/'`tools/heimdal-strength.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) tools/$(DEPDIR)/tools_heimdal_strength-heimdal-strength.Tpo tools/$(DEPDIR)/tools_heimdal_strength-heimdal-strength.Po
check-local: $(check_PROGRAMS) tests/data/dictionary.pwd
cd tests && ./runtests -l $(abs_top_srcdir)/tests/TESTS
+# Used by maintainers to run the main test suite under valgrind. Suppress
+# the xmalloc and pod-spelling tests because the former won't work properly
+# under valgrind (due to increased memory usage) and the latter is pointless
+# to run under valgrind. Don't try to trace the test for cdbmake-wordlist,
+# since it's pure Perl.
+check-valgrind: $(check_PROGRAMS) tests/data/dictionary.pwd
+ rm -rf $(abs_top_builddir)/tmp-valgrind
+ mkdir $(abs_top_builddir)/tmp-valgrind
+ env RRA_MAINTAINER_TESTS= valgrind --leak-check=full \
+ --show-reachable=yes --trace-children=yes \
+ --log-file=$(abs_top_builddir)/tmp-valgrind/log.%p \
+ --suppressions=tests/data/valgrind.supp \
+ --trace-children-skip="/bin/sh,*/cat,*/diff,*/expr,*/grep,*/mkdir,*/rm,*/rmdir,*/sed,*/sleep,*/true,*/wc,*/docs/*-t,*/perl/*-t,*/data/make-krb5-conf,*/tools/cdbmake-wordlist-t" \
+ tests/runtests -l '$(abs_top_srcdir)/tests/TESTS'
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
User-Visible krb5-strength Changes
+krb5-strength 2.2 (2013-12-16)
+
+ More complex character class requirements can be specified with the
+ configuration option require_classes. This option lists the character
+ classes the password must contain. These restrictions may be
+ qualified with password length ranges, allowing the requirements to
+ change with the length of the password. See README for more details
+ and the option syntax.
+
+ cdbmake-wordlist now supports filtering out words based on maximum
+ length (-L) and arbitrary user-provided regular expressions (-x). It
+ also supports running in filter mode to produce a new wordlist instead
+ of a CDB file (-o).
+
+ Close a file descriptor and memory leak in the included version of
+ CrackLib. This problem was already fixed in CrackLib 2.9.0.
+
+ Update to rra-c-util 4.12:
+
+ * Properly check the return status of snprintf and friends.
+
+ Update to C TAP Harness 2.3:
+
+ * Suppress lazy plans and test summaries if the test failed with bail.
+ * Add warn_unused_result gcc attributes to relevant functions.
+
krb5-strength 2.1 (2013-10-10)
Fix the package build when CDB support is disabled or TinyCDB was not
- krb5-strength 2.1
+ krb5-strength 2.2
(Kerberos password strength checking plugin)
- Maintained by Russ Allbery <rra@stanford.edu>
+ Maintained by Russ Allbery <eagle@eyrie.org>
Copyright 2006, 2007, 2009, 2010, 2012, 2013 The Board of Trustees of
the Leland Stanford Junior University. Portions copyright 1993 Alec
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.
+ contain particular character classes, or any combination of these tests.
It supports both Heimdal and MIT Kerberos (1.9 or later).
DESCRIPTION
checks and comes with an example that checks passwords against CrackLib.
However, in testing at Stanford, we found that CrackLib with its default
transform rules does not catch passwords that can be guessed using the
- same dictionary with other tools, such as Jack the Ripper.
+ same dictionary with other tools, such as Jack the Ripper. We then
+ discovered other issues with CrackLib with longer passwords, such as
+ some bad assumptions about how certain measures of complexity will
+ scale, and wanted to impose other limitations that it didn't support.
This plugin provides the ability to check password quality against the
standard version of CrackLib, or against a modified version of CrackLib
that only passes passwords that resist attacks from both Crack and Jack
- the Ripper using the same rule sets. For Heimdal, it includes both a
- program usable as an external password quality check and a plugin that
- implements the dynamic module API. For MIT Kerberos (1.9 or later), it
- includes a plugin for the password quality (pwqual) plugin API.
+ the Ripper using the same rule sets. It also supports doing simpler
+ dictionary checks against a CDB database, which is fast with very large
+ dictionaries, and imposing other programmatic checks on passwords such
+ as character class requirements.
+
+ For Heimdal, it includes both a program usable as an external password
+ quality check and a plugin that implements the dynamic module API. For
+ MIT Kerberos (1.9 or later), it includes a plugin for the password
+ quality (pwqual) plugin API.
krb5-strength can be built with either the system CrackLib or with the
modified version of CrackLib included in this package. Note, however,
You can also optionally build against the TinyCDB library, which
provides support for simpler and faster password checking against a CDB
- dictionary file. Building a CDB dictionary with cdbmake-wordlist
- (included) requires Perl 5.006 or later and the CDB utility that comes
- with TinyCDB.
+ dictionary file.
For this module to be effective for either Heimdal or MIT Kerberos, you
will also need to construct a dictionary. The mkdict and packer
in this toolkit but not installed by default. You can run them out of
the cracklib directory after building. You can also use the utilities
that come with the stock CrackLib package (often already packaged in a
- Linux distribution); the database format is compatible. For building a
- CDB dictionary, use the provided cdbmake-wordlist program. The CDB
- utility must be on your PATH.
+ Linux distribution); the database format is compatible.
+
+ For building a CDB dictionary, use the provided cdbmake-wordlist
+ program. The CDB utility must be on your PATH. cdbmake-wordlist
+ requires Perl 5.006 or later.
For a word list to use as source for the dictionary, you can use
/usr/share/dict/words if it's available on your system, but it would be
following additional Perl modules will be used by the test suite if
present:
- File::Slurp
IPC::Run
JSON
+ Perl6::Slurp
Test::MinimumVersion
Test::Perl::Critic
Test::Pod
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
files it includes and need to regenerate configure or config.h.in, you
- will need Autoconf 2.64 or later.
+ will need Autoconf 2.64 or later. You will also need Perl 5.010 or
+ later and the JSON, Perl6::Slurp, and Readonly modules (from CPAN) to
+ bootstrap the test suite data from a Git checkout.
COMPILING AND INSTALLING
dictionary. The provided path should be the full path to the dictionary
files, omitting the trailing *.hwm, *.pwd, and *.pwi extensions for the
CrackLib dictionary. You can use either or both settings. If you use
- both, CrackLib will be checked first, and then CDB.
+ both, CrackLib will be checked first, and then CDB. When checking a CDB
+ database, the password, the password with the first character removed,
+ the last character removed, the first and last characters removed, the
+ first two characters removed, and the last two characters removed will
+ all be checked against the dictionary.
Then, for the external password checking program, add a new section (or
modify the existing [password_quality] section) to look like the
dictionary. The provided path should be the full path to the dictionary
files, omitting the trailing *.hwm, *.pwd, and *.pwi extensions for the
CrackLib dictionary. You can use either or both settings. If you use
- both, CrackLib will be checked first, and then CDB.
+ both, CrackLib will be checked first, and then CDB. When checking a CDB
+ database, the password, the password with the first character removed,
+ the last character removed, the first and last characters removed, the
+ first two characters removed, and the last two characters removed will
+ all be checked against the dictionary.
The second option is to use the normal dict_path setting. In the
[realms] section of your krb5.conf kdc.conf, under the appropriate realm
interoperability problems with computers with different default
character sets or Unicode normalization forms.
+ require_classes
+
+ This option allows specification of more complex character class
+ requirements. The value of this parameter should be one or more
+ whitespace-separated rule. Each rule has the syntax:
+
+ [<min>-<max>:]<class>[,<class>...]
+
+ where <class> is one of "upper", "lower", "digit", or "symbol"
+ (without the quote marks). The symbol class includes all characters
+ other than alphanumeric characters, including space. The listed
+ classes must appear in the password. Separate multiple required
+ classes with a comma (and no space).
+
+ The character class checks will be done in whatever locale the
+ plugin or password check program is run in, which will normally be
+ the POSIX C locale but may be different depending on local
+ configuration.
+
+ A simple example:
+
+ require_classes = upper,lower,digit
+
+ This requires all passwords contain at least one uppercase letter,
+ at least one lowercase letter, and at least one digit.
+
+ If present, <min> and <max> specify the minimum password length and
+ maximum password length to which this rule applies. This allows one
+ to specify character class requirements that change with password
+ length. So, for example:
+
+ require_classes = 8-19:upper,lower 8-15:digit 8-11:symbol
+
+ requires all passwords from 8 to 11 characters long contain all four
+ character classes, passwords from 12 to 15 characters long contain
+ upper and lower case and a digit, and passwords from 16 to 19
+ characters long contain both upper and lower case. Passowrds longer
+ than 20 characters have no character class restrictions. (This
+ example is probably used in conjunction with minimum_length = 8.)
+
require_non_letter
If set to a true boolean value, the password must contain at least
will always have the current version of this package, the current
documentation, and pointers to any additional resources.
- I welcome bug reports and patches for this package at rra@stanford.edu.
+ I welcome bug reports and patches for this package at eagle@eyrie.org.
However, please be aware that I tend to be extremely busy and work
projects often take priority. I'll save your mail and get to it as soon
as I can, but it may take me a couple of months.
* Use the realm of the principal changing its password to determine the
krb5.conf configuration rather than always using the default realm.
+
+ * Refactor the tests for configuration errors in the heimdal-strength
+ test suite into JSON.
#undef HAVE_KADM5_KADM5_PWCHECK_H
/* Define to enable Kerberos features. */
-#undef HAVE_KERBEROS
+#undef HAVE_KRB5
/* Define to 1 if you have the `krb5_free_default_realm' function. */
#undef HAVE_KRB5_FREE_DEFAULT_REALM
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
+/* Define to 1 if you have the `strndup' function. */
+#undef HAVE_STRNDUP
+
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for krb5-strength 2.1.
+# Generated by GNU Autoconf 2.69 for krb5-strength 2.2.
#
-# Report bugs to <rra@stanford.edu>.
+# Report bugs to <eagle@eyrie.org>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
$as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
- $as_echo "$0: Please tell bug-autoconf@gnu.org and rra@stanford.edu
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and eagle@eyrie.org
$0: about your system, including any error possibly output
$0: before this message. Then install a modern shell, or
$0: manually run the script under such a shell if you do
# Identity of this package.
PACKAGE_NAME='krb5-strength'
PACKAGE_TARNAME='krb5-strength'
-PACKAGE_VERSION='2.1'
-PACKAGE_STRING='krb5-strength 2.1'
-PACKAGE_BUGREPORT='rra@stanford.edu'
+PACKAGE_VERSION='2.2'
+PACKAGE_STRING='krb5-strength 2.2'
+PACKAGE_BUGREPORT='eagle@eyrie.org'
PACKAGE_URL=''
ac_config_libobj_dir=portable
# 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.1 to adapt to many kinds of systems.
+\`configure' configures krb5-strength 2.2 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.1:";;
+ short | recursive ) echo "Configuration of krb5-strength 2.2:";;
esac
cat <<\_ACEOF
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
-Report bugs to <rra@stanford.edu>.
+Report bugs to <eagle@eyrie.org>.
_ACEOF
ac_status=$?
fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-krb5-strength configure 2.1
+krb5-strength configure 2.2
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ------------------------------- ##
-## Report this to rra@stanford.edu ##
-## ------------------------------- ##"
+( $as_echo "## ------------------------------ ##
+## Report this to eagle@eyrie.org ##
+## ------------------------------ ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
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.1, which was
+It was created by krb5-strength $as_me 2.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='krb5-strength'
- VERSION='2.1'
+ VERSION='2.2'
cat >>confdefs.h <<_ACEOF
$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 :
+ rra_use_CDB=true
+
+$as_echo "#define HAVE_CDB 1" >>confdefs.h
+
fi
rra_system_cracklib=
rra_cracklib_root=
rra_krb5_root=
rra_krb5_libdir=
rra_krb5_includedir=
- rra_use_kerberos=true
+ rra_use_KRB5=true
if test "x$ac_cv_lib_com_err_com_err" = xyes; then :
KRB5_LIBS="$KRB5_LIBS -lcom_err"
else
+ if test x"true" = xtrue; then :
as_fn_error $? "cannot find usable com_err library" "$LINENO" 5
+else
+ KRB5_LIBS=""
+fi
fi
for ac_header in et/com_err.h
fi
fi
rra_krb5_uses_com_err=false
- case $LIBS in #(
+ case $KRB5_LIBS in #(
*-lcom_err*) :
rra_krb5_uses_com_err=true ;; #(
*) :
fi
-$as_echo "#define HAVE_KERBEROS 1" >>confdefs.h
+$as_echo "#define HAVE_KRB5 1" >>confdefs.h
rra_krb5_save_CPPFLAGS="$CPPFLAGS"
rra_krb5_save_LDFLAGS="$LDFLAGS"
for ac_func in krb5_free_default_realm \
krb5_free_string \
- krb5_principal_get_realm \
krb5_get_init_creds_opt_alloc \
krb5_get_init_creds_opt_set_default_flags \
+ krb5_principal_get_realm \
krb5_xfree
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
fi
+ac_fn_c_check_func "$LINENO" "strndup" "ac_cv_func_strndup"
+if test "x$ac_cv_func_strndup" = xyes; then :
+ $as_echo "#define HAVE_STRNDUP 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" strndup.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strndup.$ac_objext"
+ ;;
+esac
+
+fi
+
ac_config_files="$ac_config_files Makefile"
# 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.1, which was
+This file was extended by krb5-strength $as_me 2.2, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
Configuration commands:
$config_commands
-Report bugs to <rra@stanford.edu>."
+Report bugs to <eagle@eyrie.org>."
_ACEOF
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.1
+krb5-strength config.status 2.2
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
dnl Process this file with autoconf to produce a configure script.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2006, 2007, 2009, 2010, 2012, 2013
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl Basic Autoconf configuration.
AC_PREREQ([2.64])
-AC_INIT([krb5-strength], [2.1], [rra@stanford.edu])
+AC_INIT([krb5-strength], [2.2], [eagle@eyrie.org])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_LIBOBJ_DIR([portable])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AM_DISABLE_STATIC
-AC_PROG_LIBTOOL
+LT_INIT
dnl External libraries.
RRA_LIB_CDB_OPTIONAL
AC_CHECK_TYPES([krb5_realm], [], [], [RRA_INCLUDES_KRB5])
AC_CHECK_FUNCS([krb5_free_default_realm \
krb5_free_string \
- krb5_principal_get_realm \
krb5_get_init_creds_opt_alloc \
krb5_get_init_creds_opt_set_default_flags \
+ krb5_principal_get_realm \
krb5_xfree])
AC_CHECK_FUNCS([krb5_get_init_creds_opt_free],
[RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS])
[#include <sys/types.h>])
RRA_FUNC_SNPRINTF
AC_CHECK_FUNCS([setrlimit])
-AC_REPLACE_FUNCS([asprintf])
+AC_REPLACE_FUNCS([asprintf strndup])
dnl Write out the results.
AC_CONFIG_FILES([Makefile])
* Remove last block optimization in GetPW and start fresh each time.
* Close the dictionary after each password lookup.
* Set hidden visibility on all CrackLib symbols.
+ * Close the wfp file handle on PWClose if it's open.
Below is the original changelog for CrackLib:
/*
* Modified as part of the krb5-strength project as follows:
*
- * 2007-03-22 Russ Allbery <rra@stanford.edu>
+ * 2007-03-22 Russ Allbery <eagle@eyrie.org>
* - Add four-, five-, and six-character prefix and suffix rules.
* - Longer passwords must contain more different characters, up to 8.
* - Disable GECOS checking (useless for a server).
* - Replace exit(-1) with return when dictionary doesn't exist.
* - Additional system includes for other functions.
- * 2009-10-14 Russ Allbery <rra@stanford.edu>
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Add ANSI C protototypes for all functions.
* - Tweaks for const cleanliness.
* - Add parentheses around assignment used for its truth value.
* - Change a variable to unsigned int to avoid gcc warnings.
* - Remove the unused FascistGecos function.
- * 2012-05-11 Russ Allbery <rra@stanford.edu>
+ * 2012-05-11 Russ Allbery <eagle@eyrie.org>
* - Change MINLENGTH to 8.
* - Use a separate buffer to hold the reversed password.
* - Also check whether a password is a duplicated dictionary word.
- * 2013-09-24 Russ Allbery <rra@stanford.edu>
+ * 2013-09-24 Russ Allbery <eagle@eyrie.org>
* - Replaced MAXSTEP with allowing one increment per four characters.
* - Changed error for very short passwords to match current CrackLib.
* - Close the dictionary after each password lookup.
/*
* Modified as part of the krb5-strength project as follows:
*
- * 2009-10-14 Russ Allbery <rra@stanford.edu>
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Add ANSI C protototypes for all functions.
- * 2010-03-14 Russ Allbery <rra@stanford.edu>
+ * 2010-03-14 Russ Allbery <eagle@eyrie.org>
* - Use unsigned long instead of int32 to avoid printf warnings.
*/
/*
* Modified as part of the krb5-strength project as follows:
*
- * 2007-03-23 Russ Allbery <rra@stanford.edu>
+ * 2007-03-23 Russ Allbery <eagle@eyrie.org>
* - Add ANSI C prototypes and prototype additional functions.
- * 2009-10-14 Russ Allbery <rra@stanford.edu>
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Prototype changes for const cleanliness.
- * 2010-03-14 Russ Allbery <rra@stanford.edu>
+ * 2010-03-14 Russ Allbery <eagle@eyrie.org>
* - Fix int8, int16, and int32 definitions.
- * 2013-10-01 Russ Allbery <rra@stanford.edu>
+ * 2013-10-01 Russ Allbery <eagle@eyrie.org>
* - Set hidden visibility on all symbols by default.
*/
/*
* Modified as part of the krb5-strength project as follows:
*
- * 2007-03-23 Russ Allbery <rra@stanford.edu>
+ * 2007-03-23 Russ Allbery <eagle@eyrie.org>
* - Apply Debian patch to improve the search logic.
* - Don't crash if the dictionary is corrupt.
* - Additional system includes for other functions.
- * 2009-10-14 Russ Allbery <rra@stanford.edu>
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Add ANSI C protototypes for all functions.
* - Tweaks for const cleanliness.
* - Add parentheses around assignment used for its truth value.
* - Make internal functions static.
* - Remove unused variables.
- * 2009-11-18 Russ Allbery <rra@stanford.edu>
+ * 2009-11-18 Russ Allbery <eagle@eyrie.org>
* - Fixed the data format output by packer to properly pad the end.
- * 2013-09-24 Russ Allbery <rra@stanford.edu>
+ * 2013-09-24 Russ Allbery <eagle@eyrie.org>
* - Add a missing ANSI C prototype.
* - Remove last block optimization in GetPW and start fresh each time.
+ * 2013-12-13 Russ Allbery <eagle@eyrie.org>
+ * - Close the wfp file handle on PWClose if it's open.
*/
#include <stdio.h>
pdesc.header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ if (wfp != NULL)
+ {
+ fclose(wfp);
+ }
return ((PWDICT *) 0);
}
pdesc.header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ if (wfp != NULL)
+ {
+ fclose(wfp);
+ }
return ((PWDICT *) 0);
}
pdesc.header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ if (wfp != NULL)
+ {
+ fclose(wfp);
+ }
return ((PWDICT *) 0);
}
fclose(pwp->ifp);
fclose(pwp->dfp);
+ if (pwp->wfp != NULL)
+ {
+ fclose(pwp->wfp);
+ }
pwp->header.pih_magic = 0;
/*
* Modified as part of the krb5-strength project as follows:
*
- * 2007-03-22 Russ Allbery <rra@stanford.edu>
+ * 2007-03-22 Russ Allbery <eagle@eyrie.org>
* - Cap deletion of leading or trailing characters at one more than half
* the length of the password string and no more than five characters.
* This goes with a change to fascist.c that adds rules to delete more
* leading and trailing characters for longer passwords.
* - Additional system includes for other functions.
- * 2009-10-14 Russ Allbery <rra@stanford.edu>
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Simplify Debug() function for how it's actually called.
* - Add ANSI C protototypes for all functions.
* - Tweaks for const cleanliness.
/*
* Modified as part of the krb5-strength project as follows:
*
- * 2007-03-23 Russ Allbery <rra@stanford.edu>
+ * 2007-03-23 Russ Allbery <eagle@eyrie.org>
* - Additional system includes for other functions.
- * 2009-10-14 Russ Allbery <rra@stanford.edu>
+ * 2009-10-14 Russ Allbery <eagle@eyrie.org>
* - Add ANSI C protototypes for all functions.
* - Remove unused Clone function.
*/
-krb5-strength (2.1-1~sbp60+1) squeeze-backports; urgency=low
+krb5-strength (2.2-1~sbp60+1) squeeze-backports; urgency=low
* Special Stanford-only local backport that builds the package against
Heimdal instead of MIT Kerberos. We only need the heimdal-strength
program and the MIT API isn't supported until wheezy.
- -- Russ Allbery <rra@debian.org> Tue, 05 Nov 2013 12:00:21 -0800
+ -- Russ Allbery <rra@debian.org> Mon, 16 Dec 2013 15:56:00 -0800
+
+krb5-strength (2.2-1) unstable; urgency=low
+
+ * New upstream release.
+ - Support for more complex length-sensitive character class
+ restrictions using the new require_classes configuration setting.
+ - cdbmake-wordlist now supports filtering out words based on maximum
+ length and user-supplied regular expressions, and supports running
+ in filter mode to generate a new word list.
+ * Update to standards version 3.9.5 (no changes required).
+
+ -- Russ Allbery <rra@debian.org> Mon, 16 Dec 2013 15:36:29 -0800
krb5-strength (2.1-1) unstable; urgency=low
libipc-run-perl, libjson-perl, libperl6-slurp-perl, libreadonly-perl,
libtest-pod-perl, libtest-minimumversion-perl, libtest-strict-perl, perl,
tinycdb
-Standards-Version: 3.9.4
+Standards-Version: 3.9.5
Homepage: http://www.eyrie.org/~eagle/software/krb5-strength/
Vcs-Git: git://git.eyrie.org/kerberos/krb5-strength.git -b debian
Vcs-Browser: http://git.eyrie.org/?p=kerberos/krb5-strength.git
License: Expat
Files: *
-Copyright: 2000-2002, 2004-2012 Russ Allbery <rra@stanford.edu>
+Copyright: 2000-2002, 2004-2013 Russ Allbery <eagle@eyrie.org>
2001-2002, 2004-2013
The Board of Trustees of the Leland Stanford Junior University
2010 the Massachusetts Institute of Technology
Files: portable/asprintf.c portable/dummy.c portable/kadmin.h
portable/krb5-extra.c portable/krb5.h portable/macros.h portable/stdbool.h
- portable/system.h tests/portable/asprintf-t.c util/macros.h
+ portable/strndup.c portable/system.h tests/portable/asprintf-t.c
+ tests/portable/strndup-t.c util/macros.h
Copyright: no copyright notice, see License
License: rra-public-domain
The authors hereby relinquish any claim to any copyright that they may
Files: portable/snprintf.c tests/portable/snprintf-t.c
Copyright: 1995 Patrick Powell
- 2000-2006 Russ Allbery <rra@stanford.edu>
+ 2000-2006 Russ Allbery <eagle@eyrie.org>
2001 Hrvoje Niksic
2009-2010 The Board of Trustees of the Leland Stanford Junior University
License: Powell-snprintf
on all source code distributions
Files: tests/HOWTO tools/heimdal-strength.1 tools/heimdal-strength.pod
-Copyright: 2010 Russ Allbery <rra@stanford.edu>
+Copyright: 2010 Russ Allbery <eagle@eyrie.org>
2010, 2013 The Board of Trustees of the Leland Stanford Junior University
License: all-permissive
Copying and distribution of this file, with or without modification, are
dnl
dnl Depends on RRA_SET_LDFLAGS.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2010
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2011, 2012
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl RRA_LIB_KRB5_SWITCH to set CPPFLAGS, LDFLAGS, and LIBS to include the
dnl Kerberos libraries, saving the current values first, and
dnl RRA_LIB_KRB5_RESTORE to restore those settings to before the last
-dnl RRA_LIB_KRB5_SWITCH. HAVE_KERBEROS will always be defined if RRA_LIB_KRB5
-dnl is used.
+dnl RRA_LIB_KRB5_SWITCH. HAVE_KRB5 will always be defined if RRA_LIB_KRB5 is
+dnl used.
dnl
dnl If KRB5_CPPFLAGS, KRB5_LDFLAGS, or KRB5_LIBS are set before calling these
dnl macros, their values will be added to whatever the macros discover.
dnl
dnl Provides the RRA_LIB_KRB5_OPTIONAL macro, which should be used if Kerberos
-dnl support is optional. This macro will still always set the substitution
-dnl variables, but they'll be empty unless --with-krb5 is given. Also,
-dnl HAVE_KERBEROS will be defined if --with-krb5 is given and
-dnl $rra_use_kerberos will be set to "true".
+dnl support is optional. In this case, Kerberos libraries are mandatory if
+dnl --with-krb5 is given, and will not be probed for if --without-krb5 is
+dnl given. Otherwise, they'll be probed for but will not be required.
+dnl Defines HAVE_KRB5 and sets rra_use_KRB5 to true if the libraries are
+dnl found. The substitution variables will always be set, but they will be
+dnl empty unless Kerberos libraries are found and the user did not disable
+dnl Kerberos support.
dnl
dnl Sets the Automake conditional KRB5_USES_COM_ERR saying whether we use
dnl com_err, since if we're also linking with AFS libraries, we may have to
dnl change library ordering in that case.
dnl
-dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS.
+dnl Depends on RRA_KRB5_CONFIG, RRA_ENABLE_REDUCED_DEPENDS, and
+dnl RRA_SET_LDFLAGS.
dnl
dnl Also provides RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS, which checks
dnl whether krb5_get_init_creds_opt_free takes one argument or two. Defines
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011
+dnl Written by Russ Allbery <eagle@eyrie.org>
+dnl Copyright 2005, 2006, 2007, 2008, 2009, 2010, 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
dnl and/or distribute it, with or without modifications, as long as this
dnl notice is preserved.
+dnl Ignore Automake conditionals if not using Automake.
+m4_define_default([AM_CONDITIONAL], [:])
+
dnl Headers to include when probing for Kerberos library properties.
AC_DEFUN([RRA_INCLUDES_KRB5], [[
#if HAVE_KRB5_H
[RRA_INCLUDES_KRB5])],
[AC_CHECK_LIB([com_err], [com_err],
[KRB5_LIBS="$KRB5_LIBS -lcom_err"],
- [AC_MSG_ERROR([cannot find usable com_err library])])
+ [AS_IF([test x"$1" = xtrue],
+ [AC_MSG_ERROR([cannot find usable com_err library])],
+ [KRB5_LIBS=""])])
AC_CHECK_HEADERS([et/com_err.h])])])])])
RRA_LIB_KRB5_RESTORE])
[_RRA_LIB_KRB5_PATHS
_RRA_LIB_KRB5_MANUAL([$1])])])
rra_krb5_uses_com_err=false
- AS_CASE([$LIBS], [*-lcom_err*], [rra_krb5_uses_com_err=true])
- AM_CONDITIONAL([KRB5_USES_COM_ERR], [test x"$rra_krb5_uses_com_err" = xtrue])])
+ AS_CASE([$KRB5_LIBS], [*-lcom_err*], [rra_krb5_uses_com_err=true])
+ AM_CONDITIONAL([KRB5_USES_COM_ERR],
+ [test x"$rra_krb5_uses_com_err" = xtrue])])
dnl The main macro for packages with mandatory Kerberos support.
AC_DEFUN([RRA_LIB_KRB5],
[rra_krb5_root=
rra_krb5_libdir=
rra_krb5_includedir=
- rra_use_kerberos=true
+ rra_use_KRB5=true
AC_SUBST([KRB5_CPPFLAGS])
AC_SUBST([KRB5_LDFLAGS])
AC_SUBST([KRB5_LIBS])
[AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
[rra_krb5_libdir="$withval"])])
_RRA_LIB_KRB5_INTERNAL([true])
- AC_DEFINE([HAVE_KERBEROS], 1, [Define to enable Kerberos features.])])
+ AC_DEFINE([HAVE_KRB5], 1, [Define to enable Kerberos features.])])
dnl The main macro for packages with optional Kerberos support.
AC_DEFUN([RRA_LIB_KRB5_OPTIONAL],
[rra_krb5_root=
rra_krb5_libdir=
rra_krb5_includedir=
- rra_use_kerberos=
+ rra_use_KRB5=
AC_SUBST([KRB5_CPPFLAGS])
AC_SUBST([KRB5_LDFLAGS])
AC_SUBST([KRB5_LIBS])
[AS_HELP_STRING([--with-krb5@<:@=DIR@:>@],
[Location of Kerberos headers and libraries])],
[AS_IF([test x"$withval" = xno],
- [rra_use_kerberos=false],
+ [rra_use_KRB5=false],
[AS_IF([test x"$withval" != xyes], [rra_krb5_root="$withval"])
- rra_use_kerberos=true])])
+ rra_use_KRB5=true])])
AC_ARG_WITH([krb5-include],
[AS_HELP_STRING([--with-krb5-include=DIR],
[Location of Kerberos headers])],
[AS_IF([test x"$withval" != xyes && test x"$withval" != xno],
[rra_krb5_libdir="$withval"])])
- AS_IF([test x"$rra_use_kerberos" != xfalse],
- [AS_IF([test x"$rra_use_kerberos" = xtrue],
+ AS_IF([test x"$rra_use_KRB5" != xfalse],
+ [AS_IF([test x"$rra_use_KRB5" = xtrue],
[_RRA_LIB_KRB5_INTERNAL([true])],
[_RRA_LIB_KRB5_INTERNAL([false])])],
[AM_CONDITIONAL([KRB5_USES_COM_ERR], [false])])
AS_IF([test x"$KRB5_LIBS" != x],
- [AC_DEFINE([HAVE_KERBEROS], 1, [Define to enable Kerberos features.])])])
+ [rra_use_KRB5=true
+ AC_DEFINE([HAVE_KRB5], 1, [Define to enable Kerberos features.])])])
dnl Source used by RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS.
AC_DEFUN([_RRA_FUNC_KRB5_OPT_FREE_ARGS_SOURCE], [RRA_INCLUDES_KRB5] [[
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2005, 2006, 2007
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl take as one of the arguments the prefix string to use for variables, which
dnl is usually something like "KRB5" or "GSSAPI".
dnl
-dnl Depends on RRA_ENABLE_REDUCED_DEPENDS and RRA_SET_LDFLAGS.
+dnl Depends on RRA_SET_LDFLAGS.
dnl
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2011, 2013
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2008, 2009
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2006, 2008, 2009
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl Provides the macros RRA_LIB_CDB and RRA_LIB_CDB_OPTIONAL and sets the
dnl substitution variables CDB_CPPFLAGS, CDB_LDFLAGS, and CDB_LIBS. Also
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. Defines HAVE_CDB and sets rra_use_CDB to true if the
-dnl library is found.
+dnl the TinyCDB libraries, saving the current values, and RRA_LIB_CDB_RESTORE
+dnl to restore those settings to before the last RRA_LIB_CDB_SWITCH. Defines
+dnl HAVE_CDB and sets rra_use_CDB to true if the library is found.
dnl
-dnl Depends on the lib-helper.m4 infrastructure.
+dnl Depends on the lib-helper.m4 framework.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
-dnl Copyright 2010, 2013
+dnl The canonical version of this file is maintained in the rra-c-util
+dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+dnl
+dnl Written by Russ Allbery <eagle@eyrie.org>
+dnl Copyright 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
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_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])
- rra_use_CDB=true],
+ AC_CHECK_LIB([cdb], [cdb_init], [CDB_LIBS=-lcdb],
[AS_IF([test x"$1" = xtrue],
[AC_MSG_ERROR([cannot find usable TinyCDB library])])])
AC_CHECK_HEADERS([cdb.h])
RRA_LIB_CDB_RESTORE])
-dnl The main macro for packages with mandatory kadmin client support.
+dnl The main macro for packages with mandatory TinyCDB support.
AC_DEFUN([RRA_LIB_CDB],
[RRA_LIB_HELPER_VAR_INIT([CDB])
RRA_LIB_HELPER_WITH([tinycdb], [TinyCDB], [CDB])
- _RRA_LIB_CDB_INTERNAL([true])])
+ _RRA_LIB_CDB_INTERNAL([true])
+ rra_use_CDB=true
+ AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])])
-dnl The main macro for packages with optional kadmin client support.
+dnl The main macro for packages with optional TinyCDB support.
AC_DEFUN([RRA_LIB_CDB_OPTIONAL],
[RRA_LIB_HELPER_VAR_INIT([CDB])
RRA_LIB_HELPER_WITH_OPTIONAL([tinycdb], [TinyCDB], [CDB])
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])])])])
+ [_RRA_LIB_CDB_INTERNAL([false])])])
+ AS_IF([test x"$CDB_LIBS" != x],
+ [rra_use_CDB=true
+ AC_DEFINE([HAVE_CDB], 1, [Define if libcdb is available.])])])
dnl The canonical version of this file is maintained in the rra-c-util
dnl package, available at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
-dnl Written by Russ Allbery <rra@stanford.edu>
+dnl Written by Russ Allbery <eagle@eyrie.org>
dnl Copyright 2006, 2008, 2009
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
* or end, two characters removed from the start, two from the end, or one
* character from both start and end.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2013
* The Board of Trustees of the Leland Stanford Junior University
*
--- /dev/null
+/*
+ * Password strength checks for character classes.
+ *
+ * Checks whether the password satisfies a set of character class rules.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2013
+ * The Board of Trustees of the Leland Stanford Junior University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <ctype.h>
+
+#include <plugin/internal.h>
+
+/* Stores the characteristics of a particular password as boolean flags. */
+struct password_classes {
+ bool lower;
+ bool upper;
+ bool digit;
+ bool symbol;
+};
+
+/* Abbreviate the most common error reporting syntax. */
+#define MUST_HAVE(ctx, err) \
+ strength_error_class((ctx), "password must contain " err)
+
+
+/*
+ * Analyze a password and fill out a struct with flags indicating which
+ * character classes are present in the password.
+ */
+static void
+analyze_password(const char *password, struct password_classes *classes)
+{
+ const char *p;
+
+ memset(classes, 0, sizeof(struct password_classes));
+ for (p = password; *p != '\0'; p++) {
+ if (islower((unsigned char) *p))
+ classes->lower = true;
+ else if (isupper((unsigned char) *p))
+ classes->upper = true;
+ else if (isdigit((unsigned char) *p))
+ classes->digit = true;
+ else
+ classes->symbol = true;
+ }
+}
+
+
+/*
+ * Check whether a password satisfies a required character class rule, given
+ * the length of the password and the classes. Returns 0 if it does and a
+ * Kerberos error code if it does not.
+ */
+static krb5_error_code
+check_rule(krb5_context ctx, struct class_rule *rule, size_t length,
+ struct password_classes *classes)
+{
+ if (length < rule->min || (rule->max > 0 && length > rule->max))
+ return 0;
+ if (rule->lower && !classes->lower)
+ return MUST_HAVE(ctx, "a lowercase letter");
+ if (rule->upper && !classes->upper)
+ return MUST_HAVE(ctx, "an uppercase letter");
+ if (rule->digit && !classes->digit)
+ return MUST_HAVE(ctx, "a number");
+ if (rule->symbol && !classes->symbol)
+ return MUST_HAVE(ctx, "a space or punctuation character");
+ return 0;
+}
+
+
+/*
+ * Check whether a password satisfies the configured character class
+ * restrictions.
+ */
+krb5_error_code
+strength_check_classes(krb5_context ctx, krb5_pwqual_moddata data,
+ const char *password)
+{
+ struct password_classes classes;
+ size_t length;
+ struct class_rule *rule;
+ krb5_error_code code;
+
+ if (data->rules == NULL)
+ return 0;
+ analyze_password(password, &classes);
+ length = strlen(password);
+ for (rule = data->rules; rule != NULL; rule = rule->next) {
+ code = check_rule(ctx, rule, length, &classes);
+ if (code != 0)
+ return code;
+ }
+ return 0;
+}
* settings from krb5.conf. This wraps the somewhat awkward
* krb5_appdefaults_* functions.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2013
* The Board of Trustees of the Leland Stanford Junior University
*
#include <portable/krb5.h>
#include <portable/system.h>
+#include <ctype.h>
#include <errno.h>
#include <plugin/internal.h>
#endif /* !HAVE_KRB5_REALM */
+/*
+ * Helper function to parse a number. Takes the string to parse, the unsigned
+ * int in which to store the number, and the pointer to set to the first
+ * invalid character after the number. Returns true if a number could be
+ * successfully parsed and false otherwise.
+ */
+static bool
+parse_number(const char *string, unsigned long *result, const char **end)
+{
+ unsigned long value;
+
+ errno = 0;
+ value = strtoul(string, (char **) end, 10);
+ if (errno != 0 || *end == string)
+ return false;
+ *result = value;
+ return true;
+}
+
+
/*
* Load a boolean option from Kerberos appdefaults. Takes the Kerberos
* context, the option, and the result location.
}
+/*
+ * Parse a single class specification. Currently, this assumes that the class
+ * specification is a comma-separated list of required classes, and those
+ * classes are required for any length of password. This will be enhanced
+ * later.
+ */
+static krb5_error_code
+parse_class(krb5_context ctx, const char *spec, struct class_rule **rule)
+{
+ struct vector *classes = NULL;
+ size_t i;
+ krb5_error_code code;
+ const char *end;
+ bool okay;
+
+ /* Create the basic rule structure. */
+ *rule = calloc(1, sizeof(struct class_rule));
+ if (*rule == NULL)
+ return strength_error_system(ctx, "cannot allocate memory");
+
+ /*
+ * If the rule starts with a digit, it starts with a range of affected
+ * password lengths. Parse that range.
+ */
+ if (isdigit((unsigned char) *spec)) {
+ okay = parse_number(spec, &(*rule)->min, &end);
+ if (okay)
+ okay = (*end == '-');
+ if (okay)
+ okay = parse_number(end + 1, &(*rule)->max, &end);
+ if (okay)
+ okay = (*end == ':');
+ if (okay)
+ spec = end + 1;
+ else {
+ code = strength_error_config(ctx, "bad character class requirement"
+ " in configuration: %s", spec);
+ goto fail;
+ }
+ }
+
+ /* Parse the required classes into a vector. */
+ classes = strength_vector_split_multi(spec, ",", NULL);
+ if (classes == NULL) {
+ code = strength_error_system(ctx, "cannot allocate memory");
+ goto fail;
+ }
+
+ /*
+ * Walk the list of required classes and set our flags, diagnosing an
+ * unknown character class.
+ */
+ for (i = 0; i < classes->count; i++) {
+ if (strcmp(classes->strings[i], "upper") == 0)
+ (*rule)->upper = true;
+ else if (strcmp(classes->strings[i], "lower") == 0)
+ (*rule)->lower = true;
+ else if (strcmp(classes->strings[i], "digit") == 0)
+ (*rule)->digit = true;
+ else if (strcmp(classes->strings[i], "symbol") == 0)
+ (*rule)->symbol = true;
+ else {
+ code = strength_error_config(ctx, "unknown character class %s",
+ classes->strings[i]);
+ goto fail;
+ }
+ }
+ strength_vector_free(classes);
+ return 0;
+
+fail:
+ strength_vector_free(classes);
+ free(*rule);
+ *rule = NULL;
+ return code;
+}
+
+
+/*
+ * Parse character class requirements from Kerberos appdefaults. Takes the
+ * Kerberos context, the option, and the place to store the linked list of
+ * class requirements.
+ */
+krb5_error_code
+strength_config_classes(krb5_context ctx, const char *opt,
+ struct class_rule **result)
+{
+ struct vector *config = NULL;
+ struct class_rule *rules, *last, *tmp;
+ krb5_error_code code;
+ size_t i;
+
+ /* Get the basic configuration as a list. */
+ code = strength_config_list(ctx, opt, &config);
+ if (code != 0)
+ return code;
+ if (config == NULL || config->count == 0) {
+ *result = NULL;
+ return 0;
+ }
+
+ /* Each word in the list will be a class rule. */
+ code = parse_class(ctx, config->strings[0], &rules);
+ if (code != 0 || rules == NULL)
+ goto fail;
+ last = rules;
+ for (i = 1; i < config->count; i++) {
+ code = parse_class(ctx, config->strings[i], &last->next);
+ if (code != 0 || last->next == NULL)
+ goto fail;
+ last = last->next;
+ }
+
+ /* Success. Free the vector and return the results. */
+ strength_vector_free(config);
+ *result = rules;
+ return 0;
+
+fail:
+ last = rules;
+ while (last != NULL) {
+ tmp = last;
+ last = last->next;
+ free(tmp);
+ }
+ strength_vector_free(config);
+ return code;
+}
+
+
+/*
+ * Load a list option from Kerberos appdefaults. Takes the Kerberos context,
+ * the option, and the result location. The option is read as a string and
+ * the split on spaces and tabs into a list.
+ *
+ * This requires an annoying workaround because one cannot specify a default
+ * value of NULL with MIT Kerberos, since MIT Kerberos unconditionally calls
+ * strdup on the default value. There's also no way to determine if memory
+ * allocation failed while parsing or while setting the default value.
+ */
+krb5_error_code
+strength_config_list(krb5_context ctx, const char *opt,
+ struct vector **result)
+{
+ realm_type realm;
+ char *value = NULL;
+
+ /* Obtain the string from [appdefaults]. */
+ realm = default_realm(ctx);
+ krb5_appdefault_string(ctx, "krb5-strength", realm, opt, "", &value);
+ free_default_realm(ctx, realm);
+
+ /* If we got something back, store it in result. */
+ if (value != NULL) {
+ if (value[0] != '\0') {
+ *result = strength_vector_split_multi(value, " \t", *result);
+ if (*result == NULL)
+ return strength_error_system(ctx, "cannot allocate memory");
+ }
+ krb5_free_string(ctx, value);
+ }
+ return 0;
+}
+
+
/*
* Load a number option from Kerberos appdefaults. Takes the Kerberos
* context, the option, and the result location. The native interface doesn't
* against a CrackLib dictionary.
*
* Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates,
- * on behalf of Stanford University.
- * Extensive modifications by Russ Allbery <rra@stanford.edu>
+ * on behalf of Stanford University
+ * Extensive modifications by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2012, 2013
- * The Board of Trustees of the Leland Stanford Junior Unversity
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
* Provides helper functions for the rest of the plugin code to store an error
* message in the Kerberos context.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2013
* The Board of Trustees of the Leland Stanford Junior University
*
return code; \
}
ERROR_FUNC(class, KADM5_PASS_Q_CLASS)
+ERROR_FUNC(config, KADM5_MISSING_KRB5_CONF_PARAMS)
ERROR_FUNC(dict, KADM5_PASS_Q_DICT)
ERROR_FUNC(generic, KADM5_PASS_Q_GENERIC)
ERROR_FUNC(tooshort, KADM5_PASS_Q_TOOSHORT)
* wrapped up in those interfaces.
*
* Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates,
- * on behalf of Stanford University.
- * Extensive modifications by Russ Allbery <rra@stanford.edu>
+ * on behalf of Stanford University
+ * Extensive modifications by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2012, 2013
- * The Board of Trustees of the Leland Stanford Junior Unversity
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
/* Get minimum length information from krb5.conf. */
strength_config_number(ctx, "minimum_length", &data->minimum_length);
- /* Get character class restrictions from krb5.conf. */
+ /* Get simple character class restrictions from krb5.conf. */
strength_config_boolean(ctx, "require_ascii_printable", &data->ascii);
strength_config_boolean(ctx, "require_non_letter", &data->nonletter);
+ /* Get complex character class restrictions from krb5.conf. */
+ code = strength_config_classes(ctx, "require_classes", &data->rules);
+ if (code != 0)
+ goto fail;
+
/*
* Try to initialize CDB and CrackLib dictionaries. Both functions handle
* their own configuration parsing and will do nothing if the
if (data->nonletter && only_alpha_space(password))
return strength_error_class(ctx, ERROR_LETTER);
+ /*
+ * If desired, check that the password satisfies character class
+ * restrictions.
+ */
+ code = strength_check_classes(ctx, data, password);
+ if (code != 0)
+ return code;
+
/* Check if the password is based on the principal in some way. */
code = strength_check_principal(ctx, data, principal, password);
if (code != 0)
void
strength_close(krb5_context ctx UNUSED, krb5_pwqual_moddata data)
{
- if (data != NULL) {
- strength_close_cdb(ctx, data);
- free(data->dictionary);
- free(data);
+ struct class_rule *last, *tmp;
+
+ if (data == NULL)
+ return;
+ strength_close_cdb(ctx, data);
+ last = data->rules;
+ while (last != NULL) {
+ tmp = last;
+ last = last->next;
+ free(tmp);
}
+ free(data->dictionary);
+ free(data);
}
* Of course, the external Heimdal strength checking program can be used
* instead.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2013
- * The Board of Trustees of the Leland Stanford Junior Unversity
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
* Prototypes for the kadmin password strength checking plugin.
*
* Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates,
- * on behalf of Stanford University.
- * Extensive modifications by Russ Allbery <rra@stanford.edu>
+ * on behalf of Stanford University
+ * Extensive modifications by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2012, 2013
- * The Board of Trustees of the Leland Stanford Junior Unversity
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
#ifdef HAVE_CDB_H
# include <cdb.h>
#endif
+#include <stddef.h>
#ifdef HAVE_KRB5_PWQUAL_PLUGIN_H
# include <krb5/pwqual_plugin.h>
#define ERROR_SHORT "password is too short"
#define ERROR_USERNAME "password based on username or principal"
+/*
+ * A character class rule, which consists of a minimum length to which the
+ * rule is applied, a maximum length to which the rule is applied, and a set
+ * of flags for which character classes are required. The symbol class
+ * includes everything that isn't in one of the other classes, including
+ * space.
+ */
+struct class_rule {
+ unsigned long min;
+ unsigned long max;
+ bool lower;
+ bool upper;
+ bool digit;
+ bool symbol;
+ struct class_rule *next;
+};
+
+/* Used to store a list of strings, managed by the sync_vector_* functions. */
+struct vector {
+ size_t count;
+ size_t allocated;
+ char **strings;
+};
+
/*
* MIT Kerberos uses this type as an abstract data type for any data that a
* password quality check needs to carry. Reuse it since then we get type
long minimum_length; /* Minimum password length */
bool ascii; /* Whether to require printable ASCII */
bool nonletter; /* Whether to require a non-letter */
+ struct class_rule *rules; /* Linked list of character class rules */
char *dictionary; /* Base path to CrackLib dictionary */
bool have_cdb; /* Whether we have a CDB dictionary */
int cdb_fd; /* File descriptor of CDB dictionary */
krb5_error_code strength_check_cracklib(krb5_context, krb5_pwqual_moddata,
const char *password);
+/* Check whether the password statisfies character class requirements. */
+krb5_error_code strength_check_classes(krb5_context, krb5_pwqual_moddata,
+ const char *password);
+
/* Check whether the password is based on the principal in some way. */
krb5_error_code strength_check_principal(krb5_context, krb5_pwqual_moddata,
const char *principal,
const char *password);
+/*
+ * Manage vectors, which are counted lists of strings. The functions that
+ * return a boolean return false if memory allocation fails.
+ */
+struct vector *strength_vector_new(void)
+ __attribute__((__malloc__));
+bool strength_vector_add(struct vector *, const char *string)
+ __attribute__((__nonnull__));
+void strength_vector_free(struct vector *);
+
+/*
+ * vector_split_multi splits on a set of characters. If the vector argument
+ * is NULL, a new vector is allocated; otherwise, the provided one is reused.
+ * Returns NULL on memory allocation failure, after which the provided vector
+ * may have been modified to only have partial results.
+ *
+ * Empty strings will yield zero-length vectors. Adjacent delimiters are
+ * treated as a single delimiter by vector_split_multi. Any leading or
+ * trailing delimiters are ignored, so this function will never create
+ * zero-length strings (similar to the behavior of strtok).
+ */
+struct vector *strength_vector_split_multi(const char *string,
+ const char *seps, struct vector *)
+ __attribute__((__nonnull__(1, 2)));
+
/*
* Obtain configuration settings from krb5.conf. These are wrappers around
* the krb5_appdefault_* APIs that handle setting the section name, obtaining
*/
void strength_config_boolean(krb5_context, const char *, bool *)
__attribute__((__nonnull__));
+krb5_error_code strength_config_list(krb5_context, const char *,
+ struct vector **)
+ __attribute__((__nonnull__));
void strength_config_number(krb5_context, const char *, long *)
__attribute__((__nonnull__));
void strength_config_string(krb5_context, const char *, char **)
__attribute__((__nonnull__));
+/* Parse the more complex configuration of required character classes. */
+krb5_error_code strength_config_classes(krb5_context, const char *,
+ struct class_rule **)
+ __attribute__((__nonnull__));
+
/*
* Store a particular password quality error in the Kerberos context. The
* _system variant uses errno for the error code and appends the strerror
*/
krb5_error_code strength_error_class(krb5_context, const char *format, ...)
__attribute__((__nonnull__, __format__(printf, 2, 3)));
+krb5_error_code strength_error_config(krb5_context, const char *format, ...)
+ __attribute__((__nonnull__, __format__(printf, 2, 3)));
krb5_error_code strength_error_dict(krb5_context, const char *format, ...)
__attribute__((__nonnull__, __format__(printf, 2, 3)));
krb5_error_code strength_error_generic(krb5_context, const char *format, ...)
* components of the principal.
*
* Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates,
- * on behalf of Stanford University.
- * Extensive modifications by Russ Allbery <rra@stanford.edu>
+ * on behalf of Stanford University
+ * Extensive modifications by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2012, 2013
- * The Board of Trustees of the Leland Stanford Junior Unversity
+ * The Board of Trustees of the Leland Stanford Junior University
*
* See LICENSE for licensing terms.
*/
--- /dev/null
+/*
+ * Vector handling (counted lists of char *'s).
+ *
+ * A vector is a table for handling a list of strings with less overhead than
+ * linked list. The intention is for vectors, once allocated, to be reused;
+ * this saves on memory allocations once the array of char *'s reaches a
+ * stable size.
+ *
+ * This is based on the from rra-c-util util/vector.c library, but that
+ * library uses xmalloc routines to exit the program if memory allocation
+ * fails. This is a modified version of the vector library that instead
+ * returns false on failure to allocate memory, allowing the caller to do
+ * appropriate recovery.
+ *
+ * Vectors require list of strings, not arbitrary binary data, and cannot
+ * handle data elements containing nul characters.
+ *
+ * Only the portions of the vector library needed by this module is
+ * implemented.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2013
+ * The Board of Trustees of the Leland Stanford Junior University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <plugin/internal.h>
+
+
+/*
+ * Allocate a new, empty vector. Returns NULL if memory allocation fails.
+ */
+struct vector *
+strength_vector_new(void)
+{
+ return calloc(1, sizeof(struct vector));
+}
+
+
+/*
+ * Resize a vector (using realloc to resize the table). Return false if
+ * memory allocation fails.
+ */
+static bool
+strength_vector_resize(struct vector *vector, size_t size)
+{
+ size_t i;
+ char **strings;
+
+ /* If we're shrinking the vector, free the excess strings. */
+ if (vector->count > size) {
+ for (i = size; i < vector->count; i++)
+ free(vector->strings[i]);
+ vector->count = size;
+ }
+
+ /* If resizing to zero, free all storage. Otherwise, realloc. */
+ if (size == 0) {
+ free(vector->strings);
+ vector->strings = NULL;
+ } else {
+ strings = realloc(vector->strings, size * sizeof(char *));
+ if (strings == NULL)
+ return false;
+ vector->strings = strings;
+ }
+ vector->allocated = size;
+ return true;
+}
+
+
+/*
+ * Add a new string to the vector, resizing the vector as necessary. The
+ * vector is resized an element at a time; if a lot of resizes are expected,
+ * vector_resize should be called explicitly with a more suitable size.
+ * Return false if memory allocation fails.
+ */
+bool
+strength_vector_add(struct vector *vector, const char *string)
+{
+ size_t next = vector->count;
+
+ if (vector->count == vector->allocated)
+ if (!strength_vector_resize(vector, vector->allocated + 1))
+ return false;
+ vector->strings[next] = strdup(string);
+ if (vector->strings[next] == NULL)
+ return false;
+ vector->count++;
+ return true;
+}
+
+
+/*
+ * Empty a vector but keep the allocated memory for the pointer table.
+ */
+static void
+strength_vector_clear(struct vector *vector)
+{
+ size_t i;
+
+ for (i = 0; i < vector->count; i++)
+ if (vector->strings[i] != NULL)
+ free(vector->strings[i]);
+ vector->count = 0;
+}
+
+
+/*
+ * Free a vector completely.
+ */
+void
+strength_vector_free(struct vector *vector)
+{
+ if (vector == NULL)
+ return;
+ strength_vector_clear(vector);
+ free(vector->strings);
+ free(vector);
+}
+
+
+/*
+ * Given a vector that we may be reusing, clear it out. If the first argument
+ * is NULL, allocate a new vector. Used by vector_split*. Returns NULL if
+ * memory allocation fails.
+ */
+static struct vector *
+strength_vector_reuse(struct vector *vector)
+{
+ if (vector == NULL)
+ return strength_vector_new();
+ else {
+ strength_vector_clear(vector);
+ return vector;
+ }
+}
+
+
+/*
+ * Given a string and a set of separators expressed as a string, count the
+ * number of strings that it will split into when splitting on those
+ * separators.
+ */
+static size_t
+split_multi_count(const char *string, const char *seps)
+{
+ const char *p;
+ size_t count;
+
+ /* If the string is empty, the count of components is zero. */
+ if (*string == '\0')
+ return 0;
+
+ /* Otherwise, walk the string looking for non-consecutive separators. */
+ for (count = 1, p = string + 1; *p != '\0'; p++)
+ if (strchr(seps, *p) != NULL && strchr(seps, p[-1]) == NULL)
+ count++;
+
+ /*
+ * If the string ends in separators, we've overestimated the number of
+ * strings by one.
+ */
+ if (strchr(seps, p[-1]) != NULL)
+ count--;
+ return count;
+}
+
+
+/*
+ * Given a string, split it at any of the provided separators to form a
+ * vector, copying each string segment. If the third argument isn't NULL,
+ * reuse that vector; otherwise, allocate a new one. Any number of
+ * consecutive separators are considered a single separator. Returns NULL on
+ * memory allocation failure, after which the provided vector may only have
+ * partial results.
+ */
+struct vector *
+strength_vector_split_multi(const char *string, const char *seps,
+ struct vector *vector)
+{
+ const char *p, *start;
+ size_t i, count;
+ bool created = false;
+
+ /* Set up the vector we'll use to store the results. */
+ if (vector == NULL)
+ created = true;
+ vector = strength_vector_reuse(vector);
+ if (vector == NULL)
+ return NULL;
+
+ /* Count how big a vector we need and resize accordingly. */
+ count = split_multi_count(string, seps);
+ if (count == 0)
+ return vector;
+ if (vector->allocated < count && !strength_vector_resize(vector, count))
+ goto fail;
+
+ /* Now, walk the string and build the components. */
+ vector->count = 0;
+ for (start = string, p = string, i = 0; *p != '\0'; p++)
+ if (strchr(seps, *p) != NULL) {
+ if (start != p) {
+ vector->strings[i] = strndup(start, (size_t) (p - start));
+ if (vector->strings[i] == NULL)
+ goto fail;
+ i++;
+ vector->count++;
+ }
+ start = p + 1;
+ }
+
+ /* If there is anything left in the string, we have one more component. */
+ if (start != p) {
+ vector->strings[i] = strndup(start, (size_t) (p - start));
+ if (vector->strings[i] == NULL)
+ goto fail;
+ vector->count++;
+ }
+ return vector;
+
+fail:
+ if (created)
+ strength_vector_free(vector);
+ return NULL;
+}
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
#include <config.h>
#include <portable/system.h>
+#include <errno.h>
+
/*
* If we're running the test suite, rename the functions to avoid conflicts
* with the system versions.
int test_vasprintf(char **, const char *, va_list);
#endif
+
int
asprintf(char **strp, const char *fmt, ...)
{
return status;
}
+
int
vasprintf(char **strp, const char *fmt, va_list args)
{
va_list args_copy;
- int status, needed;
+ int status, needed, oerrno;
va_copy(args_copy, args);
needed = vsnprintf(NULL, 0, fmt, args_copy);
if (status >= 0)
return status;
else {
+ oerrno = errno;
free(*strp);
*strp = NULL;
+ errno = oerrno;
return status;
}
}
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
# define KADM5_PASS_Q_GENERIC KADM5_PASS_Q_DICT
#endif
+/* Heimdal doesn't define KADM5_MISSING_KRB5_CONF_PARAMS. */
+#ifndef KADM5_MISSING_KRB5_CONF_PARAMS
+# define KADM5_MISSING_KRB5_CONF_PARAMS KADM5_MISSING_CONF_PARAMS
+#endif
+
/*
* Heimdal provides _ctx functions that take an existing context. MIT always
* requires the context be passed in. Code should use the _ctx variant, and
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* Replacement for a missing snprintf or vsnprintf.
*
* The following implementation of snprintf was taken mostly verbatim from
- * <http://www.fiction.net/~blong/programs/>; it is the version of snprintf
- * used in Mutt.
+ * <http://www.fiction.net/blong/programs/>; it is the version of snprintf
+ * used in Mutt. A possibly newer version is used in wget, found at
+ * <https://github.com/wertarbyte/wget/blob/master/src/snprintf.c>.
*
* Please do not reformat or otherwise change this file more than necessary so
* that later merges with the original source are easy. Bug fixes and
* fixed handling of %.0f
* added test for HAVE_LONG_DOUBLE
*
- * Russ Allbery <rra@stanford.edu> 2000-08-26
+ * Russ Allbery <eagle@eyrie.org> 2000-08-26
* fixed return value to comply with C99
* fixed handling of snprintf(NULL, ...)
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
--- /dev/null
+/*
+ * Replacement for a missing strndup.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+/*
+ * If we're running the test suite, rename the functions to avoid conflicts
+ * with the system versions.
+ */
+#if TESTING
+# undef strndup
+# define strndup test_strndup
+char *test_strndup(const char *, size_t);
+#endif
+
+char *
+strndup(const char *s, size_t n)
+{
+ const char *p;
+ size_t length;
+ char *copy;
+
+ if (s == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Don't assume that the source string is nul-terminated. */
+ for (p = s; (size_t) (p - s) < n && *p != '\0'; p++)
+ ;
+ length = p - s;
+ copy = malloc(length + 1);
+ if (copy == NULL)
+ return NULL;
+ memcpy(copy, s, length);
+ copy[length] = '\0';
+ return copy;
+}
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
#if !HAVE_DECL_VSNPRINTF
extern int vsnprintf(char *, size_t, const char *, va_list);
#endif
+#if !HAVE_STRNDUP
+extern char *strndup(const char *, size_t);
+#endif
/* Undo default visibility change. */
#pragma GCC visibility pop
This file is part of the documentation of C TAP Harness, which can be
found at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
- Copyright 2010 Russ Allbery <rra@stanford.edu>
+ Copyright 2010 Russ Allbery <eagle@eyrie.org>
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
perl/strict
portable/asprintf
portable/snprintf
+portable/strndup
tools/cdbmake-wordlist
tools/heimdal-strength
util/messages
#!/bin/sh
#
-# Generate a krb5.conf file with an [appdefault] password_dictionary setting
-# pointing to the password dictionary we generated for the build. This script
-# is used by C tests to set up the environment.
+# Generate a krb5.conf file with an [appdefault] krb5-strength section that
+# contains all the key/value pairs given on the command line. This script is
+# used by C tests to set up the environment.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2009, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
--- /dev/null
+/*
+ * Automatically generated -- do not edit!
+ *
+ * This file was automatically generated from the original JSON source file
+ * for the use in C test programs. To make changes, modify the original
+ * JSON source or (more rarely) the make-c-data script and run it again.
+ *
+ * Copyright 2013
+ * The Board of Trustees of the Leland Stanford Junior University
+ *
+ * See LICENSE for licensing terms.
+ */
+
+#include <tests/data/passwords/tests.h>
+
+const struct password_test classes_tests[] = {
+ {
+
+ "no lowercase (11)",
+ "test@EXAMPLE.ORG",
+ "PASSWORD98!",
+ KADM5_PASS_Q_CLASS,
+ "password must contain a lowercase letter",
+ },
+ {
+
+ "no uppercase (11)",
+ "test@EXAMPLE.ORG",
+ "password98!",
+ KADM5_PASS_Q_CLASS,
+ "password must contain an uppercase letter",
+ },
+ {
+
+ "no digit (11)",
+ "test@EXAMPLE.ORG",
+ "passwordXX!",
+ KADM5_PASS_Q_CLASS,
+ "password must contain a number",
+ },
+ {
+
+ "no symbol (11)",
+ "test@EXAMPLE.ORG",
+ "passwordXX9",
+ KADM5_PASS_Q_CLASS,
+ "password must contain a space or punctuation character",
+ },
+ {
+
+ "all classes (11)",
+ "test@EXAMPLE.ORG",
+ "passwordX9!",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes with space (11)",
+ "test@EXAMPLE.ORG",
+ "pass wordX9",
+ 0,
+ NULL,
+ },
+ {
+
+ "no lowercase (15)",
+ "test@EXAMPLE.ORG",
+ "PASSWORD98!WORD",
+ KADM5_PASS_Q_CLASS,
+ "password must contain a lowercase letter",
+ },
+ {
+
+ "no uppercase (15)",
+ "test@EXAMPLE.ORG",
+ "password98!word",
+ KADM5_PASS_Q_CLASS,
+ "password must contain an uppercase letter",
+ },
+ {
+
+ "no digit (15)",
+ "test@EXAMPLE.ORG",
+ "passwordXX!word",
+ KADM5_PASS_Q_CLASS,
+ "password must contain a number",
+ },
+ {
+
+ "no symbol (12)",
+ "test@EXAMPLE.ORG",
+ "passwordXX9w",
+ 0,
+ NULL,
+ },
+ {
+
+ "no symbol (15)",
+ "test@EXAMPLE.ORG",
+ "passwordXX9word",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes (15)",
+ "test@EXAMPLE.ORG",
+ "passwordX9!word",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes with space (15)",
+ "test@EXAMPLE.ORG",
+ "pass wordX9word",
+ 0,
+ NULL,
+ },
+ {
+
+ "no lowercase (19)",
+ "test@EXAMPLE.ORG",
+ "PASSWORD98!WORDWORD",
+ KADM5_PASS_Q_CLASS,
+ "password must contain a lowercase letter",
+ },
+ {
+
+ "no uppercase (19)",
+ "test@EXAMPLE.ORG",
+ "password98!wordword",
+ KADM5_PASS_Q_CLASS,
+ "password must contain an uppercase letter",
+ },
+ {
+
+ "no digit (16)",
+ "test@EXAMPLE.ORG",
+ "passwordXX!wordw",
+ 0,
+ NULL,
+ },
+ {
+
+ "no digit (19)",
+ "test@EXAMPLE.ORG",
+ "passwordXX!wordword",
+ 0,
+ NULL,
+ },
+ {
+
+ "no symbol (19)",
+ "test@EXAMPLE.ORG",
+ "passwordXX9wordword",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes (19)",
+ "test@EXAMPLE.ORG",
+ "passwordX9!wordword",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes with space (19)",
+ "test@EXAMPLE.ORG",
+ "pass wordX9wordword",
+ 0,
+ NULL,
+ },
+ {
+
+ "no lowercase (20)",
+ "test@EXAMPLE.ORG",
+ "PASSWORD98!WORDWORDW",
+ 0,
+ NULL,
+ },
+ {
+
+ "no uppercase (20)",
+ "test@EXAMPLE.ORG",
+ "password98!wordwordw",
+ 0,
+ NULL,
+ },
+ {
+
+ "no digit (20)",
+ "test@EXAMPLE.ORG",
+ "passwordXX!wordwordw",
+ 0,
+ NULL,
+ },
+ {
+
+ "no symbol (20)",
+ "test@EXAMPLE.ORG",
+ "passwordXX9wordwordw",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes (20)",
+ "test@EXAMPLE.ORG",
+ "passwordX9!wordwordw",
+ 0,
+ NULL,
+ },
+ {
+
+ "all classes with space (20)",
+ "test@EXAMPLE.ORG",
+ "pass wordX9wordwordw",
+ 0,
+ NULL,
+ },
+};
--- /dev/null
+[
+ {
+ "name": "no lowercase (11)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "PASSWORD98!",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain a lowercase letter"
+ },
+ {
+ "name": "no uppercase (11)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "password98!",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain an uppercase letter"
+ },
+ {
+ "name": "no digit (11)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX!",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain a number"
+ },
+ {
+ "name": "no symbol (11)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX9",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain a space or punctuation character"
+ },
+ {
+ "name": "all classes (11)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordX9!"
+ },
+ {
+ "name": "all classes with space (11)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "pass wordX9"
+ },
+ {
+ "name": "no lowercase (15)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "PASSWORD98!WORD",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain a lowercase letter"
+ },
+ {
+ "name": "no uppercase (15)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "password98!word",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain an uppercase letter"
+ },
+ {
+ "name": "no digit (15)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX!word",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain a number"
+ },
+ {
+ "name": "no symbol (12)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX9w"
+ },
+ {
+ "name": "no symbol (15)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX9word"
+ },
+ {
+ "name": "all classes (15)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordX9!word"
+ },
+ {
+ "name": "all classes with space (15)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "pass wordX9word"
+ },
+ {
+ "name": "no lowercase (19)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "PASSWORD98!WORDWORD",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain a lowercase letter"
+ },
+ {
+ "name": "no uppercase (19)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "password98!wordword",
+ "code": "KADM5_PASS_Q_CLASS",
+ "error": "password must contain an uppercase letter"
+ },
+ {
+ "name": "no digit (16)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX!wordw"
+ },
+ {
+ "name": "no digit (19)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX!wordword"
+ },
+ {
+ "name": "no symbol (19)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX9wordword"
+ },
+ {
+ "name": "all classes (19)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordX9!wordword"
+ },
+ {
+ "name": "all classes with space (19)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "pass wordX9wordword"
+ },
+ {
+ "name": "no lowercase (20)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "PASSWORD98!WORDWORDW"
+ },
+ {
+ "name": "no uppercase (20)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "password98!wordwordw"
+ },
+ {
+ "name": "no digit (20)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX!wordwordw"
+ },
+ {
+ "name": "no symbol (20)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordXX9wordwordw"
+ },
+ {
+ "name": "all classes (20)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "passwordX9!wordwordw"
+ },
+ {
+ "name": "all classes with space (20)",
+ "principal": "test@EXAMPLE.ORG",
+ "password": "pass wordX9wordwordw"
+ }
+]
#include <tests/data/passwords/tests.h>
-const struct password_test class_tests[] = {
+const struct password_test letter_tests[] = {
{
"non-ASCII characters",
=head1 AUTHOR
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
* This header provides the struct definition for password test data written
* out by make-c-data. It's included by the test data files.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2013
* The Board of Trustees of the Leland Stanford Junior University
*
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2011, 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
--- /dev/null
+# -*- conf -*-
+#
+# This is a valgrind suppression file for analysis of test suite results.
+#
+# Suppress a variety of apparent memory leaks in various Kerberos
+# implementations due to one-time instantiation of data, and a few other
+# artifacts of the test suite for rra-c-util portability and utility code
+# and related software.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2011, 2012, 2013
+# The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+{
+ dlopen-dlerror
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+}
+{
+ heimdal-krb5-init-context-once
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:init_context_once
+}
+{
+ heimdal-krb5-reg-plugins-once
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:krb5_plugin_register
+ fun:reg_def_plugins_once
+}
+{
+ heimdal-krb5-openssl-init
+ Memcheck:Leak
+ fun:*alloc
+ obj:*
+ fun:CRYPTO_*alloc
+}
+{
+ mit-gss-ccache
+ Memcheck:Leak
+ fun:*alloc
+ fun:krb5int_setspecific
+ fun:kg_set_ccache_name
+ fun:gss_krb5int_ccache_name
+}
+{
+ mit-gss-ccache-2
+ Memcheck:Leak
+ fun:*alloc
+ fun:strdup
+ fun:kg_set_ccache_name
+ fun:gss_krb5int_ccache_name
+}
+{
+ mit-krb5-pkinit-openssl-init
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:krb5_init_preauth_context
+}
+{
+ mit-krb5-pkinit-openssl-request
+ Memcheck:Leak
+ fun:*alloc
+ ...
+ fun:krb5_preauth_request_context_init
+}
+{
+ mit-krb5-plugin-dirs
+ Memcheck:Leak
+ fun:calloc
+ fun:krb5int_open_plugin_dirs
+}
+{
+ mit-krb5-plugin-dlerror
+ Memcheck:Leak
+ fun:calloc
+ fun:_dlerror_run
+ ...
+ fun:krb5int_open_plugin
+}
+{
+ mit-krb5-plugin-register
+ Memcheck:Leak
+ fun:malloc
+ fun:strdup
+ fun:register_module.isra.1
+}
+{
+ portable-setenv
+ Memcheck:Leak
+ fun:malloc
+ fun:test_setenv
+}
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
/*
* Test for the Heimdal shared module API.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* named cdb_tests, cracklib_tests, and principal_tests.
*/
#include <tests/data/passwords/cdb.c>
-#include <tests/data/passwords/class.c>
+#include <tests/data/passwords/classes.c>
#include <tests/data/passwords/cracklib.c>
#include <tests/data/passwords/length.c>
+#include <tests/data/passwords/letter.c>
#include <tests/data/passwords/principal.c>
/*
* Loads the Heimdal password change plugin and tests that its metadata is
* correct. Returns a pointer to the kadm5_pw_policy_verifier struct or bails
- * on failure to load the plugin.
+ * on failure to load the plugin. Stores the handle in the last argument so
+ * that the caller can free the handle at the end of the test suite.
*/
static struct kadm5_pw_policy_verifier *
-load_plugin(void)
+load_plugin(void **handle)
{
char *path;
- void *handle;
struct kadm5_pw_policy_verifier *verifier;
/* Load the module. */
path = test_file_path("../plugin/.libs/strength.so");
if (path == NULL)
bail("cannot find plugin");
- handle = dlopen(path, RTLD_NOW);
- if (handle == NULL)
- sysbail("cannot dlopen %s: %s", path, dlerror());
+ *handle = dlopen(path, RTLD_NOW);
+ if (*handle == NULL)
+ bail("cannot dlopen %s: %s", path, dlerror());
test_file_path_free(path);
/* Find the dispatch table and do a basic sanity check. */
- verifier = dlsym(handle, "kadm5_password_verifier");
+ verifier = dlsym(*handle, "kadm5_password_verifier");
if (verifier == NULL)
- sysbail("cannot get kadm5_password_verifier symbol: %s", dlerror());
+ bail("cannot get kadm5_password_verifier symbol: %s", dlerror());
if (verifier->funcs == NULL || verifier->funcs[0].func == NULL)
bail("no verifier functions in module");
char *setup_argv[10];
size_t i, count;
struct kadm5_pw_policy_verifier *verifier;
+ void *handle;
/*
* Calculate how many tests we have. There are five tests for the module
*/
count = ARRAY_SIZE(cracklib_tests);
count += ARRAY_SIZE(cdb_tests);
- count += ARRAY_SIZE(class_tests);
+ count += ARRAY_SIZE(classes_tests);
count += ARRAY_SIZE(length_tests);
+ count += ARRAY_SIZE(letter_tests);
count += ARRAY_SIZE(principal_tests) * 2;
plan(5 + count * 2);
putenv(krb5_config_empty);
/* Load the plugin. */
- verifier = load_plugin();
+ verifier = load_plugin(&handle);
/* Set up our krb5.conf with the dictionary configuration. */
setup_argv[0] = test_file_path("data/make-krb5-conf");
for (i = 0; i < ARRAY_SIZE(principal_tests); i++)
is_password_test(verifier, &principal_tests[i]);
- /* Add character class restrictions. */
+ /* Add simple character class restrictions. */
setup_argv[5] = (char *) "require_ascii_printable";
setup_argv[6] = (char *) "true";
setup_argv[7] = (char *) "require_non_letter";
setup_argv[9] = NULL;
run_setup((const char **) setup_argv);
- /* Run the character class tests. */
- for (i = 0; i < ARRAY_SIZE(class_tests); i++)
- is_password_test(verifier, &class_tests[i]);
+ /* Run the simple character class tests. */
+ for (i = 0; i < ARRAY_SIZE(letter_tests); i++)
+ is_password_test(verifier, &letter_tests[i]);
+
+ /* Add complex character class restrictions and remove the dictionary. */
+ free(setup_argv[4]);
+ setup_argv[3] = (char *) "require_classes";
+ setup_argv[4] = (char *) "8-19:lower,upper 8-15:digit 8-11:symbol";
+ setup_argv[5] = NULL;
+ run_setup((const char **) setup_argv);
+
+ /* Run the simple character class tests. */
+ for (i = 0; i < ARRAY_SIZE(classes_tests); i++)
+ is_password_test(verifier, &classes_tests[i]);
/*
- * Add length restrictions and remove the dictionary. This should only do
- * length checks without any dictionary checks.
+ * Add length restrictions. This should only do length checks without any
+ * dictionary checks.
*/
- free(setup_argv[4]);
setup_argv[3] = (char *) "minimum_length";
setup_argv[4] = (char *) "12";
setup_argv[5] = NULL;
free(path);
test_tmpdir_free(tmpdir);
+ /* Close down the module. */
+ if (dlclose(handle) != 0)
+ bail("cannot close plugin: %s", dlerror());
+
/* Keep valgrind clean by freeing environmental memory. */
putenv((char *) "KRB5_CONFIG=");
free(krb5_config);
/*
* Test for the MIT Kerberos shared module API.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2010, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* named cdb_tests, cracklib_tests, and principal_tests.
*/
#include <tests/data/passwords/cdb.c>
-#include <tests/data/passwords/class.c>
+#include <tests/data/passwords/classes.c>
#include <tests/data/passwords/cracklib.c>
#include <tests/data/passwords/length.c>
+#include <tests/data/passwords/letter.c>
#include <tests/data/passwords/principal.c>
/*
* Loads the Heimdal password change plugin and tests that its metadata is
* correct. Returns a pointer to the kadm5_pw_policy_verifier struct or bails
- * on failure to load the plugin.
+ * on failure to load the plugin. Stores the handle from dlopen in its second
+ * argument for a later clean shutdown.
*/
static krb5_pwqual_vtable
-load_plugin(krb5_context ctx)
+load_plugin(krb5_context ctx, void **handle)
{
char *path;
- void *handle;
krb5_error_code code;
krb5_pwqual_vtable vtable = NULL;
krb5_error_code (*init)(krb5_context, int, int, krb5_plugin_vtable);
path = test_file_path("../plugin/.libs/strength.so");
if (path == NULL)
bail("cannot find plugin");
- handle = dlopen(path, RTLD_NOW);
- if (handle == NULL)
+ *handle = dlopen(path, RTLD_NOW);
+ if (*handle == NULL)
bail("cannot dlopen %s: %s", path, dlerror());
test_file_path_free(path);
/* Find the entry point function. */
- init = dlsym(handle, "pwqual_strength_initvt");
+ init = dlsym(*handle, "pwqual_strength_initvt");
if (init == NULL)
bail("cannot get pwqual_strength_initvt symbol: %s", dlerror());
krb5_pwqual_vtable vtable;
krb5_pwqual_moddata data;
krb5_error_code code;
+ void *handle;
/*
* Calculate how many tests we have. There are two tests for the module
- * metadata, five more tests for initializing the plugin, and two tests per
+ * metadata, six more tests for initializing the plugin, and two tests per
* password test.
*
* We run all the CrackLib tests twice, once with an explicit dictionary
*/
count = 2 * ARRAY_SIZE(cracklib_tests);
count += ARRAY_SIZE(cdb_tests);
- count += ARRAY_SIZE(class_tests);
+ count += ARRAY_SIZE(classes_tests);
count += ARRAY_SIZE(length_tests);
+ count += ARRAY_SIZE(letter_tests);
count += 2 * ARRAY_SIZE(principal_tests);
- plan(2 + 5 + count * 2);
+ plan(2 + 6 + count * 2);
/* Start with the krb5.conf that contains no dictionary configuration. */
path = test_file_path("data/krb5.conf");
bail_krb5(ctx, code, "cannot initialize Kerberos context");
/* Load the plugin. */
- vtable = load_plugin(ctx);
+ vtable = load_plugin(ctx, &handle);
/* Initialize the plugin with a CrackLib dictionary. */
build = getenv("BUILD");
is_password_test(ctx, vtable, data, &cracklib_tests[i]);
vtable->close(ctx, data);
- /* Add character class configuration to krb5.conf. */
+ /* Add simple character class configuration to krb5.conf. */
setup_argv[5] = (char *) "require_ascii_printable";
setup_argv[6] = (char *) "true";
setup_argv[7] = (char *) "require_non_letter";
if (code != 0)
bail_krb5(ctx, code, "cannot initialize Kerberos context");
- /* Run all the character class tests. */
+ /* Run all the simple character class tests. */
+ code = vtable->open(ctx, NULL, &data);
+ is_int(0, code, "Plugin initialization (simple character class)");
+ if (code != 0)
+ bail("cannot continue after plugin initialization failure");
+ for (i = 0; i < ARRAY_SIZE(letter_tests); i++)
+ is_password_test(ctx, vtable, data, &letter_tests[i]);
+ vtable->close(ctx, data);
+
+ /*
+ * Add complex character class configuration to krb5.conf but drop
+ * the dictionary configuration.
+ */
+ setup_argv[3] = (char *) "require_classes";
+ setup_argv[4] = (char *) "8-19:lower,upper 8-15:digit 8-11:symbol";
+ setup_argv[5] = NULL;
+ run_setup((const char **) setup_argv);
+
+ /* Obtain a new Kerberos context with that krb5.conf file. */
+ krb5_free_context(ctx);
+ code = krb5_init_context(&ctx);
+ if (code != 0)
+ bail_krb5(ctx, code, "cannot initialize Kerberos context");
+
+ /* Run all the complex character class tests. */
code = vtable->open(ctx, NULL, &data);
- is_int(0, code, "Plugin initialization (character class)");
+ is_int(0, code, "Plugin initialization (complex character class)");
if (code != 0)
bail("cannot continue after plugin initialization failure");
- for (i = 0; i < ARRAY_SIZE(class_tests); i++)
- is_password_test(ctx, vtable, data, &class_tests[i]);
+ for (i = 0; i < ARRAY_SIZE(classes_tests); i++)
+ is_password_test(ctx, vtable, data, &classes_tests[i]);
vtable->close(ctx, data);
/*
- * Add length restrictions and remove the dictionary. This should only do
- * length checks without any dictionary checks.
+ * Add length restrictions. This should only do length checks without any
+ * dictionary checks.
*/
setup_argv[3] = (char *) "minimum_length";
setup_argv[4] = (char *) "12";
#ifdef HAVE_CDB
/* If built with CDB, set up krb5.conf to use a CDB dictionary instead. */
- free(dictionary);
+ test_file_path_free(dictionary);
dictionary = test_file_path("data/wordlist.cdb");
if (dictionary == NULL)
bail("cannot find data/wordlist.cdb in the test suite");
free(path);
test_tmpdir_free(tmpdir);
+ /* Close down the module. */
+ if (dlclose(handle) != 0)
+ bail("cannot close plugin: %s", dlerror());
+
/* Keep valgrind clean by freeing all memory. */
test_file_path_free(dictionary);
krb5_free_context(ctx);
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006
- * Russ Allbery <rra@stanford.edu>
+ * Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2010
* The Board of Trustees of the Leland Stanford Junior University
* Copyright 1995 Patrick Powell
--- /dev/null
+/*
+ * strndup test suite.
+ *
+ * The canonical version of this file is maintained in the rra-c-util package,
+ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
+ *
+ * Written by Russ Allbery <eagle@eyrie.org>
+ *
+ * The authors hereby relinquish any claim to any copyright that they may have
+ * in this work, whether granted under contract or by operation of law or
+ * international treaty, and hereby commit to the public, at large, that they
+ * shall not, at any time in the future, seek to enforce any copyright in this
+ * work against any person or entity, or prevent any person or entity from
+ * copying, publishing, distributing or creating derivative works of this
+ * work.
+ */
+
+#include <config.h>
+#include <portable/system.h>
+
+#include <errno.h>
+
+#include <tests/tap/basic.h>
+
+char *test_strndup(const char *, size_t);
+
+
+int
+main(void)
+{
+ char buffer[3];
+ char *result = NULL;
+
+ plan(7);
+
+ result = test_strndup("foo", 8);
+ is_string("foo", result, "strndup longer than string");
+ free(result);
+ result = test_strndup("foo", 2);
+ is_string("fo", result, "strndup shorter than string");
+ free(result);
+ result = test_strndup("foo", 3);
+ is_string("foo", result, "strndup same size as string");
+ free(result);
+ result = test_strndup("foo", 0);
+ is_string("", result, "strndup of size 0");
+ free(result);
+ memcpy(buffer, "foo", 3);
+ result = test_strndup(buffer, 3);
+ is_string("foo", result, "strndup of non-nul-terminated string");
+ free(result);
+ errno = 0;
+ result = test_strndup(NULL, 0);
+ is_string(NULL, result, "strndup of NULL");
+ is_int(errno, EINVAL, "...and returns EINVAL");
+
+ return 0;
+}
--- /dev/null
+#define TESTING 1
+#include <portable/strndup.c>
* Harness <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
* Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011
- * Russ Allbery <rra@stanford.edu>
+ * Russ Allbery <eagle@eyrie.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* AIX doesn't have WCOREDUMP. */
#ifndef WCOREDUMP
-# define WCOREDUMP(status) ((unsigned)(status) & 0x80)
+# define WCOREDUMP(status) ((unsigned)(status) & 0x80)
#endif
/*
};
/*
- * Usage message. Should be used as a printf format with two arguments: the
- * path to runtests, given twice.
+ * Usage message. Should be used as a printf format with four arguments: the
+ * path to runtests, given three times, and the usage_description. This is
+ * split into variables to satisfy the pedantic ISO C90 limit on strings.
*/
static const char usage_message[] = "\
Usage: %s [-b <build-dir>] [-s <source-dir>] <test> ...\n\
%s [-b <build-dir>] [-s <source-dir>] -l <test-list>\n\
%s -o [-b <build-dir>] [-s <source-dir>] <test>\n\
-\n\
+\n%s";
+static const char usage_extra[] = "\
Options:\n\
-b <build-dir> Set the build directory to <build-dir>\n\
-l <list> Take the list of tests to run from <test-list>\n\
build = optarg;
break;
case 'h':
- printf(usage_message, argv[0], argv[0], argv[0]);
+ printf(usage_message, argv[0], argv[0], argv[0], usage_extra);
exit(0);
break;
case 'l':
argv += optind;
argc -= optind;
if ((list == NULL && argc < 1) || (list != NULL && argc > 0)) {
- fprintf(stderr, usage_message, argv[0], argv[0], argv[0]);
+ fprintf(stderr, usage_message, argv[0], argv[0], argv[0], usage_extra);
exit(1);
}
* This file is part of C TAP Harness. The current version plus supporting
* documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
- * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu>
+ * Copyright 2009, 2010, 2011, 2012, 2013 Russ Allbery <eagle@eyrie.org>
* Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
/*
* The test count. Always contains the number that will be used for the next
- * test status.
+ * test status. This is exported to callers of the library.
*/
unsigned long testnum = 1;
* Status information stored so that we can give a test summary at the end of
* the test case. We store the planned final test and the count of failures.
* We can get the highest test count from testnum.
- *
- * We also store the PID of the process that called plan() and only summarize
- * results when that process exits, so as to not misreport results in forked
- * processes.
- *
- * If _lazy is true, we're doing lazy planning and will print out the plan
- * based on the last test number at the end of testing.
*/
static unsigned long _planned = 0;
static unsigned long _failed = 0;
+
+/*
+ * Store the PID of the process that called plan() and only summarize
+ * results when that process exits, so as to not misreport results in forked
+ * processes.
+ */
static pid_t _process = 0;
+
+/*
+ * If true, we're doing lazy planning and will print out the plan based on the
+ * last test number at the end of testing.
+ */
static int _lazy = 0;
+/*
+ * If true, the test was aborted by calling bail(). Currently, this is only
+ * used to ensure that we pass a false value to any cleanup functions even if
+ * all tests to that point have passed.
+ */
+static int _aborted = 0;
+
+/*
+ * Registered cleanup functions. These are stored as a linked list and run in
+ * registered order by finish when the test program exits. Each function is
+ * passed a boolean value indicating whether all tests were successful.
+ */
+struct cleanup_func {
+ test_cleanup_func func;
+ struct cleanup_func *next;
+};
+static struct cleanup_func *cleanup_funcs = NULL;
+
+/*
+ * Print a specified prefix and then the test description. Handles turning
+ * the argument list into a va_args structure suitable for passing to
+ * print_desc, which has to be done in a macro. Assumes that format is the
+ * argument immediately before the variadic arguments.
+ */
+#define PRINT_DESC(prefix, format) \
+ do { \
+ if (format != NULL) { \
+ va_list args; \
+ if (prefix != NULL) \
+ printf("%s", prefix); \
+ va_start(args, format); \
+ vprintf(format, args); \
+ va_end(args); \
+ } \
+ } while (0)
+
/*
* Our exit handler. Called on completion of the test to report a summary of
* results provided we're still in the original process. This also handles
* printing out the plan if we used plan_lazy(), although that's suppressed if
- * we never ran a test (due to an early bail, for example).
+ * we never ran a test (due to an early bail, for example), and running any
+ * registered cleanup functions.
*/
static void
finish(void)
{
+ int success;
+ struct cleanup_func *current;
unsigned long highest = testnum - 1;
- if (_planned == 0 && !_lazy)
- return;
- fflush(stderr);
- if (_process != 0 && getpid() == _process) {
- if (_lazy && highest > 0) {
- printf("1..%lu\n", highest);
- _planned = highest;
+ /*
+ * Don't do anything except free the cleanup functions if we aren't the
+ * primary process (the process in which plan or plan_lazy was called).
+ */
+ if (_process != 0 && getpid() != _process) {
+ while (cleanup_funcs != NULL) {
+ current = cleanup_funcs;
+ cleanup_funcs = cleanup_funcs->next;
+ free(current);
}
- if (_planned > highest)
- printf("# Looks like you planned %lu test%s but only ran %lu\n",
- _planned, (_planned > 1 ? "s" : ""), highest);
- else if (_planned < highest)
- printf("# Looks like you planned %lu test%s but ran %lu extra\n",
- _planned, (_planned > 1 ? "s" : ""), highest - _planned);
- else if (_failed > 0)
- printf("# Looks like you failed %lu test%s of %lu\n", _failed,
- (_failed > 1 ? "s" : ""), _planned);
- else if (_planned > 1)
- printf("# All %lu tests successful or skipped\n", _planned);
- else
- printf("# %lu test successful or skipped\n", _planned);
+ return;
}
+
+ /*
+ * Determine whether all tests were successful, which is needed before
+ * calling cleanup functions since we pass that fact to the functions.
+ */
+ if (_planned == 0 && _lazy)
+ _planned = highest;
+ success = (!_aborted && _planned == highest && _failed == 0);
+
+ /*
+ * If there are any registered cleanup functions, we run those first. We
+ * always run them, even if we didn't run a test.
+ */
+ while (cleanup_funcs != NULL) {
+ cleanup_funcs->func(success);
+ current = cleanup_funcs;
+ cleanup_funcs = cleanup_funcs->next;
+ free(current);
+ }
+
+ /* Don't do anything further if we never planned a test. */
+ if (_planned == 0)
+ return;
+
+ /* If we're aborting due to bail, don't print summaries. */
+ if (_aborted)
+ return;
+
+ /* Print out the lazy plan if needed. */
+ fflush(stderr);
+ if (_lazy && _planned > 0)
+ printf("1..%lu\n", _planned);
+
+ /* Print out a summary of the results. */
+ if (_planned > highest)
+ diag("Looks like you planned %lu test%s but only ran %lu", _planned,
+ (_planned > 1 ? "s" : ""), highest);
+ else if (_planned < highest)
+ diag("Looks like you planned %lu test%s but ran %lu extra", _planned,
+ (_planned > 1 ? "s" : ""), highest - _planned);
+ else if (_failed > 0)
+ diag("Looks like you failed %lu test%s of %lu", _failed,
+ (_failed > 1 ? "s" : ""), _planned);
+ else if (_planned != 1)
+ diag("All %lu tests successful or skipped", _planned);
+ else
+ diag("%lu test successful or skipped", _planned);
}
plan(unsigned long count)
{
if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
- fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
- strerror(errno));
+ sysdiag("cannot set stdout to line buffered");
fflush(stderr);
printf("1..%lu\n", count);
testnum = 1;
_planned = count;
_process = getpid();
- atexit(finish);
+ if (atexit(finish) != 0) {
+ sysdiag("cannot register exit handler");
+ diag("cleanups will not be run");
+ }
}
plan_lazy(void)
{
if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0)
- fprintf(stderr, "# cannot set stdout to line buffered: %s\n",
- strerror(errno));
+ sysdiag("cannot set stdout to line buffered");
testnum = 1;
_process = getpid();
_lazy = 1;
- atexit(finish);
+ if (atexit(finish) != 0)
+ sysbail("cannot register exit handler to display plan");
}
{
fflush(stderr);
printf("1..0 # skip");
- if (format != NULL) {
- va_list args;
-
- putchar(' ');
- va_start(args, format);
- vprintf(format, args);
- va_end(args);
- }
+ PRINT_DESC(" ", format);
putchar('\n');
exit(0);
}
-/*
- * Print the test description.
- */
-static void
-print_desc(const char *format, va_list args)
-{
- printf(" - ");
- vprintf(format, args);
-}
-
-
/*
* Takes a boolean success value and assumes the test passes if that value
* is true and fails if that value is false.
printf("%sok %lu", success ? "" : "not ", testnum++);
if (!success)
_failed++;
- if (format != NULL) {
- va_list args;
-
- va_start(args, format);
- print_desc(format, args);
- va_end(args);
- }
+ PRINT_DESC(" - ", format);
putchar('\n');
}
printf("%sok %lu", success ? "" : "not ", testnum++);
if (!success)
_failed++;
- if (format != NULL)
- print_desc(format, args);
+ if (format != NULL) {
+ printf(" - ");
+ vprintf(format, args);
+ }
putchar('\n');
}
{
fflush(stderr);
printf("ok %lu # skip", testnum++);
- if (reason != NULL) {
- va_list args;
-
- va_start(args, reason);
- putchar(' ');
- vprintf(reason, args);
- va_end(args);
- }
+ PRINT_DESC(" ", reason);
putchar('\n');
}
printf("%sok %lu", status ? "" : "not ", testnum++);
if (!status)
_failed++;
- if (format != NULL) {
- va_list args;
-
- va_start(args, format);
- print_desc(format, args);
- va_end(args);
- }
+ PRINT_DESC(" - ", format);
putchar('\n');
}
}
fflush(stderr);
for (i = 0; i < count; i++) {
printf("ok %lu # skip", testnum++);
- if (reason != NULL) {
- va_list args;
-
- va_start(args, reason);
- putchar(' ');
- vprintf(reason, args);
- va_end(args);
- }
+ PRINT_DESC(" ", reason);
putchar('\n');
}
}
if (wanted == seen)
printf("ok %lu", testnum++);
else {
- printf("# wanted: %ld\n# seen: %ld\n", wanted, seen);
+ diag("wanted: %ld", wanted);
+ diag(" seen: %ld", seen);
printf("not ok %lu", testnum++);
_failed++;
}
- if (format != NULL) {
- va_list args;
-
- va_start(args, format);
- print_desc(format, args);
- va_end(args);
- }
+ PRINT_DESC(" - ", format);
putchar('\n');
}
if (strcmp(wanted, seen) == 0)
printf("ok %lu", testnum++);
else {
- printf("# wanted: %s\n# seen: %s\n", wanted, seen);
+ diag("wanted: %s", wanted);
+ diag(" seen: %s", seen);
printf("not ok %lu", testnum++);
_failed++;
}
- if (format != NULL) {
- va_list args;
-
- va_start(args, format);
- print_desc(format, args);
- va_end(args);
- }
+ PRINT_DESC(" - ", format);
putchar('\n');
}
if (wanted == seen)
printf("ok %lu", testnum++);
else {
- printf("# wanted: %lx\n# seen: %lx\n", (unsigned long) wanted,
- (unsigned long) seen);
+ diag("wanted: %lx", (unsigned long) wanted);
+ diag(" seen: %lx", (unsigned long) seen);
printf("not ok %lu", testnum++);
_failed++;
}
- if (format != NULL) {
- va_list args;
-
- va_start(args, format);
- print_desc(format, args);
- va_end(args);
- }
+ PRINT_DESC(" - ", format);
putchar('\n');
}
{
va_list args;
+ _aborted = 1;
fflush(stderr);
fflush(stdout);
printf("Bail out! ");
va_list args;
int oerrno = errno;
+ _aborted = 1;
fflush(stderr);
fflush(stdout);
printf("Bail out! ");
if (path != NULL)
free(path);
}
+
+
+/*
+ * Register a cleanup function that is called when testing ends. All such
+ * registered functions will be run by finish.
+ */
+void
+test_cleanup_register(test_cleanup_func func)
+{
+ struct cleanup_func *cleanup, **last;
+
+ cleanup = bmalloc(sizeof(struct cleanup_func));
+ cleanup->func = func;
+ cleanup->next = NULL;
+ last = &cleanup_funcs;
+ while (*last != NULL)
+ last = &(*last)->next;
+ *last = cleanup;
+}
* This file is part of C TAP Harness. The current version plus supporting
* documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
- * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu>
+ * Copyright 2009, 2010, 2011, 2012, 2013 Russ Allbery <eagle@eyrie.org>
* Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012
* The Board of Trustees of the Leland Stanford Junior University
*
#include <tests/tap/macros.h>
#include <stdarg.h> /* va_list */
-#include <sys/types.h> /* size_t */
+#include <stddef.h> /* size_t */
/*
* Used for iterating through arrays. ARRAY_SIZE returns the number of
void plan(unsigned long count);
/*
- * Prepare for lazy planning, in which the plan will be printed automatically
+ * Prepare for lazy planning, in which the plan will be printed automatically
* at the end of the test program.
*/
void plan_lazy(void);
/* Allocate memory, reporting a fatal error with bail on failure. */
void *bcalloc(size_t, size_t)
- __attribute__((__alloc_size__(1, 2), __malloc__));
+ __attribute__((__alloc_size__(1, 2), __malloc__, __warn_unused_result__));
void *bmalloc(size_t)
- __attribute__((__alloc_size__(1), __malloc__));
+ __attribute__((__alloc_size__(1), __malloc__, __warn_unused_result__));
void *brealloc(void *, size_t)
- __attribute__((__alloc_size__(2), __malloc__));
+ __attribute__((__alloc_size__(2), __malloc__, __warn_unused_result__));
char *bstrdup(const char *)
- __attribute__((__malloc__, __nonnull__));
+ __attribute__((__malloc__, __nonnull__, __warn_unused_result__));
char *bstrndup(const char *, size_t)
- __attribute__((__malloc__, __nonnull__));
+ __attribute__((__malloc__, __nonnull__, __warn_unused_result__));
/*
* Find a test file under BUILD or SOURCE, returning the full path. The
* returned path should be freed with test_file_path_free().
*/
char *test_file_path(const char *file)
- __attribute__((__malloc__, __nonnull__));
+ __attribute__((__malloc__, __nonnull__, __warn_unused_result__));
void test_file_path_free(char *path);
/*
* returned path should be freed with test_tmpdir_free.
*/
char *test_tmpdir(void)
- __attribute__((__malloc__));
+ __attribute__((__malloc__, __warn_unused_result__));
void test_tmpdir_free(char *path);
+/*
+ * Register a cleanup function that is called when testing ends. All such
+ * registered functions will be run during atexit handling (and are therefore
+ * subject to all the same constraints and caveats as atexit functions). The
+ * function must return void and will be passed one argument, an int that will
+ * be true if the test completed successfully and false otherwise.
+ */
+typedef void (*test_cleanup_func)(int);
+void test_cleanup_register(test_cleanup_func)
+ __attribute__((__nonnull__));
+
END_DECLS
#endif /* TAP_BASIC_H */
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2006, 2007, 2009, 2010, 2011, 2012
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2006, 2007, 2009, 2010, 2011, 2012, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* Permission is hereby granted, free of charge, to any person obtaining a
*/
#include <config.h>
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
# include <portable/krb5.h>
#endif
#include <portable/system.h>
* Kerberos libraries available and one if we don't. Uses keytab to obtain
* credentials, and fills in the cache member of the provided config struct.
*/
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
static void
kerberos_kinit(void)
free(krbtgt);
}
-#else /* !HAVE_KERBEROS */
+#else /* !HAVE_KRB5 */
static void
kerberos_kinit(void)
bail("cannot get Kerberos tickets");
}
-#endif /* !HAVE_KERBEROS */
+#endif /* !HAVE_KRB5 */
/*
* The remaining functions in this file are only available if Kerberos
* libraries are available.
*/
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
/*
return princ;
}
-#endif /* HAVE_KERBEROS */
+#endif /* HAVE_KRB5 */
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2009, 2011, 2012, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
#include <config.h>
#include <tests/tap/macros.h>
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
# include <portable/krb5.h>
#endif
void kerberos_cleanup_conf(void);
/* Thes interfaces are only available with native Kerberos support. */
-#ifdef HAVE_KERBEROS
+#ifdef HAVE_KRB5
/* Bail out with an error, appending the Kerberos error message. */
void bail_krb5(krb5_context, krb5_error_code, const char *format, ...)
krb5_principal kerberos_keytab_principal(krb5_context, const char *path)
__attribute__((__nonnull__));
-#endif /* HAVE_KERBEROS */
+#endif /* HAVE_KRB5 */
END_DECLS
# writing test cases. It is part of C TAP Harness, which can be found at
# <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2009, 2010, 2011, 2012 Russ Allbery <eagle@eyrie.org>
# Copyright 2006, 2007, 2008, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
* This file is part of C TAP Harness. The current version plus supporting
* documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
*
- * Copyright 2008, 2012 Russ Allbery <rra@stanford.edu>
+ * Copyright 2008, 2012, 2013 Russ Allbery <eagle@eyrie.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
# endif
#endif
+/* Suppress __warn_unused_result__ if gcc is too old. */
+#if !defined(__attribute__) && !defined(__warn_unused_result__)
+# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
+# define __warn_unused_result__ /* empty */
+# endif
+#endif
+
/*
* LLVM and Clang pretend to be GCC but don't support all of the __attribute__
* settings that GCC does. For them, suppress warnings about unknown
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2013
# The Board of Trustees of the Leland Stanford Junior University
#
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '4.09';
+ $VERSION = '4.12';
}
# Skip this test unless maintainer tests are requested. Takes a short
skip_unless_maintainer('Coding style tests');
# Load modules, skipping the test if they're not available.
- use_prereq('File::Slurp');
+ use_prereq('Perl6::Slurp', 'slurp');
use_prereq('Test::Script::Run', '0.04');
=head1 DESCRIPTION
=head1 AUTHOR
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2013
# The Board of Trustees of the Leland Stanford Junior University
#
# consistency is good).
BEGIN {
@ISA = qw(Exporter);
- @EXPORT_OK = qw(automake_setup perl_dirs test_file_path);
+ @EXPORT_OK = qw(automake_setup perl_dirs test_file_path test_tmpdir);
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '4.09';
+ $VERSION = '4.12';
}
# Perl directories to skip globally for perl_dirs. We ignore the perl
# distribution and has its own standalone test suite.
my @GLOBAL_SKIP = qw(.git perl);
+# The temporary directory created by test_tmpdir, if any. If this is set,
+# attempt to remove the directory stored here on program exit (but ignore
+# failure to do so).
+my $TMPDIR;
+
# Perform initial test setup for running a Perl test in an Automake package.
# This verifies that BUILD and SOURCE are set and then changes directory to
# the SOURCE directory by default. Sets LD_LIBRARY_PATH if the $LIBRARY_PATH
return;
}
+# Create a temporary directory for tests to use for transient files and return
+# the path to that directory. The directory is automatically removed on
+# program exit. The directory permissions use the current umask. Calls
+# BAIL_OUT if the directory could not be created.
+#
+# Returns: Path to a writable temporary directory
+sub test_tmpdir {
+ my $path;
+
+ # If we already figured out what directory to use, reuse the same path.
+ # Otherwise, create a directory relative to BUILD if set.
+ if (defined($TMPDIR)) {
+ $path = $TMPDIR;
+ } else {
+ my $base = defined($ENV{BUILD}) ? $ENV{BUILD} : File::Spec->curdir;
+ $path = File::Spec->catdir($base, 'tmp');
+ }
+
+ # Create the directory if it doesn't exist.
+ if (!-d $path) {
+ if (!mkdir($path, 0777)) {
+ BAIL_OUT("cannot create directory $path: $!");
+ }
+ }
+
+ # Store the directory name for cleanup and return it.
+ $TMPDIR = $path;
+ return $path;
+}
+
+# On program exit, remove $TMPDIR if set and if possible. Report errors with
+# diag but otherwise ignore them.
+END {
+ if (defined($TMPDIR) && -d $TMPDIR) {
+ local $! = undef;
+ if (!rmdir($TMPDIR)) {
+ diag("cannot remove temporary directory $TMPDIR: $!");
+ }
+ }
+}
+
1;
__END__
=for stopwords
Allbery Automake Automake-aware Automake-based rra-c-util ARGS
-subdirectories sublicense MERCHANTABILITY NONINFRINGEMENT
+subdirectories sublicense MERCHANTABILITY NONINFRINGEMENT umask
=head1 NAME
relative to SOURCE. test_file_path() returns the full path to FILE or
calls BAIL_OUT if FILE could not be found.
+=item test_tmpdir()
+
+Create a temporary directory for tests to use for transient files and
+return the path to that directory. The directory is created relative to
+the BUILD environment variable, which must be set. Permissions on the
+directory are set using the current umask. test_tmpdir() returns the full
+path to the temporary directory or calls BAIL_OUT if it could not be
+created.
+
+The directory is automatically removed if possible on program exit.
+Failure to remove the directory on exit is reported with diag() and
+otherwise ignored.
+
=back
=head1 AUTHOR
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
# This version should match the corresponding rra-c-util release, but with
# two digits for the minor version, including a leading zero if necessary,
# so that it will sort properly.
- $VERSION = '4.09';
+ $VERSION = '4.12';
}
# If BUILD or SOURCE are set in the environment, look for data/perl.conf under
=item $LIBRARY_PATH
-Add this directory (or a .libs subdirectory) relative to the top of the
+Add this directory (or a F<.libs> subdirectory) relative to the top of the
source tree to LD_LIBRARY_PATH when checking the syntax of Perl modules.
This may be required to pick up libraries that are used by in-tree Perl
modules so that Perl scripts can pass a syntax check.
=head1 AUTHOR
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2002, 2004, 2005 Russ Allbery <rra@stanford.edu>
- * Copyright 2009, 2010, 2011
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002, 2004, 2005 Russ Allbery <eagle@eyrie.org>
+ * Copyright 2009, 2010, 2011, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* Permission is hereby granted, free of charge, to any person obtaining a
p = strchr(output, '\n');
if (p != NULL)
*p = '\0';
- bail("%s", output);
+ if (output[0] != '\0')
+ bail("%s", output);
+ else
+ bail("setup command failed with no output");
}
free(output);
}
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2010
* The Board of Trustees of the Leland Stanford Junior University
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Copyright 2011, 2012 Russ Allbery <rra@stanford.edu>
+ * Copyright 2011, 2012 Russ Allbery <eagle@eyrie.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Copyright 2011, 2012 Russ Allbery <rra@stanford.edu>
+ * Copyright 2011, 2012 Russ Allbery <eagle@eyrie.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#
# Test suite for the cdbmake-wordlist utility.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2013
# The Board of Trustees of the Leland Stanford Junior University
#
fi
# Output the test plan.
-plan 11
+plan 20
# Create a temporary directory and wordlist and ensure it's writable.
tmpdir=`test_tmpdir`
ok_program 'Database does not contain non-ASCII password' 100 '' \
cdb -q "$tmpdir/wordlist.cdb" 'عربى'
+# Regenerate the database, filtering out long passwords.
+ok_program 'Database generation with no long passwords' 0 '' \
+ "$cdbmake" -L 10 "$tmpdir/wordlist"
+ok_program 'Database still contains bitterbane' 0 '1' \
+ cdb -q "$tmpdir/wordlist.cdb" bitterbane
+ok_program 'Database does not contain happenstance' 100 '' \
+ cdb -q "$tmpdir/wordlist.cdb" happenstance
+
+# Regenerate the database, filtering out words starting with b or ending in d.
+ok_program 'Database generation with no b passwords' 0 '' \
+ "$cdbmake" -x '\Ab' -x '.*d' "$tmpdir/wordlist"
+ok_program 'Database does not contain bitterbane' 100 '' \
+ cdb -q "$tmpdir/wordlist.cdb" bitterbane
+ok_program 'Database still contains happenstance' 0 '1' \
+ cdb -q "$tmpdir/wordlist.cdb" happenstance
+ok_program 'Database does not contain password' 100 '' \
+ cdb -q "$tmpdir/wordlist.cdb" password
+
+# Try filtering the wordlist into a new wordlist.
+ok_program 'Wordlist filtering' 0 '' \
+ "$cdbmake" -a -x '.*d' -l 8 -o "$tmpdir/wordlist.new" "$tmpdir/wordlist"
+( echo 'bitterbane'; echo 'happenstance' ) > "$tmpdir/wordlist.expected"
+ok_program 'Filtered wordlist is correct' 0 '' \
+ cmp "$tmpdir/wordlist.expected" "$tmpdir/wordlist.new"
+rm -f "$tmpdir/wordlist.expected" "$tmpdir/wordlist.new"
+
# Clean up.
rm -f "$tmpdir/wordlist.cdb"
rm -f "$tmpdir/wordlist"
#
# Test suite for basic Heimdal external strength checking functionality.
#
-# Written by Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
# Copyright 2009, 2012, 2013
# The Board of Trustees of the Leland Stanford Junior University
#
use Test::RRA qw(use_prereq);
use Test::RRA::Automake qw(test_file_path);
-use_prereq('File::Slurp');
use_prereq('IPC::Run', 'run');
use_prereq('JSON');
-use_prereq('Test::More', '0.87_01');
+use_prereq('Perl6::Slurp', 'slurp');
+use_prereq('Test::More', '0.87_01');
# Run the newly-built heimdal-strength command and return the status, output,
# and error output as a list.
my $program = test_file_path('../tools/heimdal-strength');
# Run the password strength checker.
- my $out;
- my $err;
+ my ($out, $err);
run([$program, $principal], \$in, \$out, \$err);
my $status = ($? >> 8);
my $path = test_file_path("data/passwords/$file");
# Load the test file data into memory.
- my $testdata = read_file($path);
+ my $testdata = slurp($path);
# Decode the JSON into Perl objects and return them.
my $json = JSON->new->utf8;
# Load the password tests from JSON. Accumulate a total count of tests for
# the testing plan.
my (%tests, $count);
-for my $type (qw(cdb class cracklib length principal)) {
+for my $type (qw(cdb classes cracklib length letter principal)) {
my $tests = load_password_tests("$type.json");
$tests{$type} = $tests;
$count += scalar(@{$tests});
# We run the principal tests twice, once for CrackLib and once for CDB.
$count += scalar(@{ $tests{principal} });
-# We can now calculate our plan based on three tests for each password test.
-plan(tests => $count * 3);
+# We can now calculate our plan based on three tests for each password test,
+# plus 21 additional tests for error handling.
+plan(tests => $count * 3 + 21);
# Install the krb5.conf file with a configuration pointing to the test
# CrackLib dictionary.
check_password($test);
}
-# Install the krb5.conf file for character class restrictions.
+# Install the krb5.conf file for simple character class restrictions.
$krb5_conf = create_krb5_conf(
{
require_ascii_printable => 'true',
);
local $ENV{KRB5_CONFIG} = $krb5_conf;
-# Run the character class tests.
-note('Password character class checks');
-for my $test (@{ $tests{class} }) {
+# Run the simple character class tests.
+note('Simple password character class checks');
+for my $test (@{ $tests{letter} }) {
+ check_password($test);
+}
+
+# Install the krb5.conf file for complex character class restrictions.
+my $classes = '8-19:lower,upper 8-15:digit 8-11:symbol';
+$krb5_conf = create_krb5_conf({ require_classes => $classes });
+local $ENV{KRB5_CONFIG} = $krb5_conf;
+
+# Run the complex character class tests.
+note('Complex password character class checks');
+for my $test (@{ $tests{classes} }) {
check_password($test);
}
}
}
+# Test error for an unknown character class.
+$krb5_conf = create_krb5_conf({ require_classes => 'bogus' });
+local $ENV{KRB5_CONFIG} = $krb5_conf;
+my $error_prefix = 'Cannot initialize strength checking';
+($status, $output, $err) = run_heimdal_strength('test', 'password');
+is($status, 1, 'Bad character class (status)');
+is($output, q{}, '...no output');
+is($err, "$error_prefix: unknown character class bogus\n", '...correct error');
+
+# Test a variety of configuration syntax errors in require_classes.
+my @bad_classes = qw(
+ 8 8bogus 8:bogus 4-:bogus 4-bogus 4-8bogus
+);
+my $bad_message = 'bad character class requirement in configuration';
+for my $bad_class (@bad_classes) {
+ $krb5_conf = create_krb5_conf({ require_classes => $bad_class });
+ local $ENV{KRB5_CONFIG} = $krb5_conf;
+ ($status, $output, $err) = run_heimdal_strength('test', 'password');
+ is($status, 1, "Bad class specification '$bad_class' (status)");
+ is($output, q{}, '...no output');
+ is($err, "$error_prefix: $bad_message: $bad_class\n", '...correct error');
+}
+
# Clean up our temporary krb5.conf file on any exit.
END {
my $tmpdir = $ENV{BUILD} ? "$ENV{BUILD}/tmp" : 'tests/tmp';
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2010, 2011, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2002, 2004, 2005 Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2002, 2004, 2005 Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2010, 2011, 2012
* The Board of Trustees of the Leland Stanford Junior University
*
# The canonical version of this file is maintained in the rra-c-util package,
# which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
#
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2000, 2001, 2006 Russ Allbery <rra@stanford.edu>
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2000, 2001, 2006 Russ Allbery <eagle@eyrie.org>
# Copyright 2008, 2009, 2010, 2012
# The Board of Trustees of the Leland Stanford Junior University
#
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Copyright 2000, 2001, 2006 Russ Allbery <rra@stanford.edu>
+ * Copyright 2000, 2001, 2006 Russ Allbery <eagle@eyrie.org>
* Copyright 2008, 2012, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
return;
}
+# Filter the given input file and write it to a CDB data file, and then use
+# cdb to turn that into a database.
+#
+# $in_fh - Input file handle for the source wordlist
+# $input - Name of the input file, from which the CDB file name is derived
+# $filter - Reference to sub that returns true to keep a word, false otherwise
+#
+# Returns: undef
+# Throws: Text exception on output failure or pre-existing temporary file
+sub write_cdb {
+ my ($in_fh, $input, $filter) = @_;
+
+ # Create a temporary file to write the CDB input into.
+ my $tmp = $input . '.data';
+ if (-f $tmp) {
+ die "$0: temporary output file $tmp already exists\n";
+ }
+ open(my $tmp_fh, '>', $tmp)
+ or die "$0: cannot create output file $tmp: $!\n";
+
+ # Walk through the input word list and write each word that passes the
+ # filter to the output file handle as CDB data.
+ while (defined(my $word = <$in_fh>)) {
+ chomp($word);
+ next if !$filter->($word);
+ my $length = length($word);
+ print_fh($tmp_fh, "+$length,1:$word->1\n");
+ }
+
+ # Add a trailing newline, required by the CDB data format, and close.
+ print_fh($tmp_fh, "\n");
+ close($tmp_fh) or die "$0: cannot write to temporary file $tmp: $!\n";
+
+ # Run cdb to turn the result into a CDB database. Ignore duplicate keys.
+ system($CDB, '-c', '-u', "$input.cdb", $tmp) == 0
+ or die "$0: cdb -c failed\n";
+
+ # Remove the temporary file and return.
+ unlink($tmp) or die "$0: cannot remove temporary file $tmp: $!\n";
+ return;
+}
+
+# Filter the given input file and write the results to a new wordlist.
+#
+# $in_fh - Input file handle for the source wordlist
+# $output - Output file name to which to write the resulting wordlist
+# $filter - Reference to sub that returns true to keep a word, false otherwise
+#
+# Returns: undef
+# Throws: Text exception on output failure
+sub write_wordlist {
+ my ($in_fh, $output, $filter) = @_;
+ open(my $out_fh, '>', $output)
+ or die "$0: cannot create output file $output: $!\n";
+
+ # Walk through the input word list and write each word that passes the
+ # filter to the output file handle.
+ while (defined(my $word = <$in_fh>)) {
+ chomp($word);
+ next if !$filter->($word);
+ print_fh($out_fh, "$word\n");
+ }
+
+ # All done.
+ close($out_fh) or die "$0: cannot write to output file $output: $!\n";
+ return;
+}
+
# Always flush output.
STDOUT->autoflush;
local $0 = basename($0);
# Parse the argument list.
-my ($ascii, $min_length, $manual);
+my ($ascii, @exclude, $max_length, $min_length, $manual, $output);
Getopt::Long::config('bundling', 'no_ignore_case');
GetOptions(
'ascii|a' => \$ascii,
+ 'max-length|L=i' => \$max_length,
'min-length|l=i' => \$min_length,
- 'manual|man|m' => \$manual
+ 'manual|man|m' => \$manual,
+ 'output|o=s' => \$output,
+ 'exclude|x=s' => \@exclude,
);
if ($manual) {
print_fh(\*STDOUT, "Feeding myself to perldoc, please wait...\n");
}
my $input = $ARGV[0];
-# The output file goes in the same directory and is named the same as the
-# input but with .data appended.
-my $output = $input . '.data';
-if (-f $output) {
- die "$0: temporary output file $output already exists\n";
-}
-
-# Process the input file into the output file, converting it to cdb input
-# format.
-open(my $in, '<', $input)
- or die "$0: cannot open input file $input: $!\n";
-open(my $out, '>', $output)
- or die "$0: cannot create output file $output: $!\n";
-while (defined(my $word = <$in>)) {
- chomp($word);
+# Build a filter from our command-line parameters. This is an anonymous sub
+# that returns true to keep a word and false otherwise.
+my $filter = sub {
+ my ($word) = @_;
my $length = length($word);
- next if (defined($min_length) && $length < $min_length);
+
+ # Check length.
+ return if (defined($min_length) && $length < $min_length);
+ return if (defined($max_length) && $length > $max_length);
+
+ # Check character classes.
if ($ascii) {
- next if $word =~ m{ [^[:ascii:]] }xms;
- next if $word =~ m{ [[:cntrl:]] }xms;
+ return if $word =~ m{ [^[:ascii:]] }xms;
+ return if $word =~ m{ [[:cntrl:]] }xms;
}
- print_fh($out, "+$length,1:$word->1\n");
-}
-print_fh($out, "\n");
-close($in) or die "$0: cannot read all of input file $input: $!\n";
-close($out) or die "$0: cannot write to output file $output: $!\n";
-# Run cdb to turn the result into a constant database. Ignore duplicate keys.
-system($CDB, '-c', '-u', "$input.cdb", $output) == 0
- or die "$0: cdb -c failed\n";
+ # Check regex exclusions.
+ for my $pattern (@exclude) {
+ return if $word =~ m{ $pattern }xms;
+ }
-# Remove the temporary file.
-unlink($output) or die "$0: cannot remove temporary file $output: $!\n";
+ # Word passes. Return success.
+ return 1;
+};
+
+# Process the input file into either wordlist output or a CDB file.
+open(my $in_fh, '<', $input)
+ or die "$0: cannot open input file $input: $!\n";
+if (defined($output)) {
+ write_wordlist($in_fh, $output, $filter);
+} else {
+ write_cdb($in_fh, $input, $filter);
+}
+close($in_fh) or die "$0: cannot read all of input file $input: $!\n";
# All done.
exit(0);
=for stopwords
cdbmake-wordlist cdb whitespace wordlist lookups lookup sublicense
-MERCHANTABILITY NONINFRINGEMENT krb5-strength --ascii Allbery
+MERCHANTABILITY NONINFRINGEMENT krb5-strength --ascii Allbery regexes
+output-wordlist
=head1 NAME
=head1 SYNOPSIS
-B<cdbmake-wordlist> [B<-am>] [B<-l> I<length>] I<wordlist>
+B<cdbmake-wordlist> [B<-am>] [B<-l> I<min-length>] [B<-L> I<max-length>]
+ [B<-o> I<output-wordlist>] [B<-x> I<exclude> ...] I<wordlist>
=head1 DESCRIPTION
output cdb database will have the same name as I<wordlist> but with
C<.cdb> appended. The input wordlist file does not have to be sorted.
+B<cdbmake-wordlist> can, instead of building a CDB file, filter a wordlist
+against the criteria given on the command line and generate a new
+wordlist. See the B<-o> option for more details.
+
=head1 OPTIONS
=over 4
from the resulting cdb file, leaving only words that consist solely of
ASCII non-control characters.
+=item B<-L> I<maximum>, B<--max-length>=I<maximum>
+
+Filter all words of length greater than I<maximum> from the resulting cdb
+database. The length of each line (minus the separating newline) in the
+input wordlist will be checked against I<minimum> and will be filtered out
+of the resulting database if it is shorter. Useful for generating
+password dictionaries from word lists that contain random noise that's
+highly unlikely to be used as a password.
+
+The default is to not filter out any words for maximum length.
+
=item B<-l> I<minimum>, B<--min-length>=I<minimum>
Filter all words of length less than I<minimum> from the resulting cdb
Print out this documentation (which is done simply by feeding the script to
C<perldoc -t>).
+=item B<-o> I<wordlist>, B<--output>=I<wordlist>
+
+Rather than creating a CDB database, apply the filter rules given by the
+other command-line arguments and generate a new wordlist in the file name
+given by the I<wordlist> option. This can be used to reduce the size of
+a raw wordlist file (such as one taken from Internet sources) by removing
+the words that will be filtered out of the CDB file anyway, thus reducing
+the size of the source required to regenerate the CDB database.
+
+If this option is given, no CDB database will be created.
+
+=item B<-x> I<exclude>, B<--exclude>=I<exclude>
+
+Filter all words matching the regular expression I<exclude> from the
+resulting cdb database. This regular expression will be matched against
+each line of the source wordlist after the trailing newline is removed.
+This option may be given repeatedly to add multiple exclusion regexes.
+
=back
=head1 AUTHOR
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
.\" ========================================================================
.\"
.IX Title "CDBMAKE-WORDLIST 1"
-.TH CDBMAKE-WORDLIST 1 "2013-10-10" "2.1" "krb5-strength"
+.TH CDBMAKE-WORDLIST 1 "2013-12-16" "2.2" "krb5-strength"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
cdbmake\-wordlist \- Create a cdb database from a wordlist
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
-\&\fBcdbmake-wordlist\fR [\fB\-am\fR] [\fB\-l\fR \fIlength\fR] \fIwordlist\fR
+\&\fBcdbmake-wordlist\fR [\fB\-am\fR] [\fB\-l\fR \fImin-length\fR] [\fB\-L\fR \fImax-length\fR]
+ [\fB\-o\fR \fIoutput-wordlist\fR] [\fB\-x\fR \fIexclude\fR ...] \fIwordlist\fR
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
cdb is a format invented by Dan Bernstein for fast, constant databases.
\&\fBcdbmake-wordlist\fR takes one argument, the input wordlist file. The
output cdb database will have the same name as \fIwordlist\fR but with
\&\f(CW\*(C`.cdb\*(C'\fR appended. The input wordlist file does not have to be sorted.
+.PP
+\&\fBcdbmake-wordlist\fR can, instead of building a \s-1CDB\s0 file, filter a wordlist
+against the criteria given on the command line and generate a new
+wordlist. See the \fB\-o\fR option for more details.
.SH "OPTIONS"
.IX Header "OPTIONS"
.IP "\fB\-a\fR, \fB\-\-ascii\fR" 4
Filter all words that contain non-ASCII characters or control characters
from the resulting cdb file, leaving only words that consist solely of
\&\s-1ASCII\s0 non-control characters.
+.IP "\fB\-L\fR \fImaximum\fR, \fB\-\-max\-length\fR=\fImaximum\fR" 4
+.IX Item "-L maximum, --max-length=maximum"
+Filter all words of length greater than \fImaximum\fR from the resulting cdb
+database. The length of each line (minus the separating newline) in the
+input wordlist will be checked against \fIminimum\fR and will be filtered out
+of the resulting database if it is shorter. Useful for generating
+password dictionaries from word lists that contain random noise that's
+highly unlikely to be used as a password.
+.Sp
+The default is to not filter out any words for maximum length.
.IP "\fB\-l\fR \fIminimum\fR, \fB\-\-min\-length\fR=\fIminimum\fR" 4
.IX Item "-l minimum, --min-length=minimum"
Filter all words of length less than \fIminimum\fR from the resulting cdb
.IX Item "-m, --man, --manual"
Print out this documentation (which is done simply by feeding the script to
\&\f(CW\*(C`perldoc \-t\*(C'\fR).
+.IP "\fB\-o\fR \fIwordlist\fR, \fB\-\-output\fR=\fIwordlist\fR" 4
+.IX Item "-o wordlist, --output=wordlist"
+Rather than creating a \s-1CDB\s0 database, apply the filter rules given by the
+other command-line arguments and generate a new wordlist in the file name
+given by the \fIwordlist\fR option. This can be used to reduce the size of
+a raw wordlist file (such as one taken from Internet sources) by removing
+the words that will be filtered out of the \s-1CDB\s0 file anyway, thus reducing
+the size of the source required to regenerate the \s-1CDB\s0 database.
+.Sp
+If this option is given, no \s-1CDB\s0 database will be created.
+.IP "\fB\-x\fR \fIexclude\fR, \fB\-\-exclude\fR=\fIexclude\fR" 4
+.IX Item "-x exclude, --exclude=exclude"
+Filter all words matching the regular expression \fIexclude\fR from the
+resulting cdb database. This regular expression will be matched against
+each line of the source wordlist after the trailing newline is removed.
+This option may be given repeatedly to add multiple exclusion regexes.
.SH "AUTHOR"
.IX Header "AUTHOR"
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
Copyright 2013 The Board of Trustees of the Leland Stanford Junior
.\" ========================================================================
.\"
.IX Title "HEIMDAL-STRENGTH 1"
-.TH HEIMDAL-STRENGTH 1 "2013-10-10" "2.1" "krb5-strength"
+.TH HEIMDAL-STRENGTH 1 "2013-12-16" "2.2" "krb5-strength"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
\&\fBheimdal-strength\fR is an external password quality check program for
-Heimdal that verifies the strength of a password using an embedded copy of
-CrackLib, with some modifications to increase the aggressiveness of its
-rules. It is normally run via \fIkpasswdd\fR\|(8) using the Heimdal password
-quality check interface rather than directly.
+Heimdal that verifies the strength of a password. Passwords can be tested
+with CrackLib, checked against a \s-1CDB\s0 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 particular
+character classes, or any combination of these tests. It is normally run
+via \fIkpasswdd\fR\|(8) using the Heimdal password quality check interface rather
+than directly.
.PP
-To use this program, the path to a CrackLib database must be configured in
-krb5.conf via the \f(CW\*(C`password_dictionary\*(C'\fR setting in \f(CW\*(C`[appdefaults]\*(C'\fR. It
-uses the application name \f(CW\*(C`krb5\-strength\*(C'\fR when trying to find this
-setting. A typical setting would be:
+To use this program, it must be configured in \fIkrb5.conf\fR via settings
+in \f(CW\*(C`[appdefaults]\*(C'\fR for the application name \f(CW\*(C`krb5\-strength\*(C'\fR. A typical
+setting would be:
.PP
.Vb 3
\& krb5\-strength = {
\& }
.Ve
.PP
+which says to check passwords with CrackLib using the given path as the
+base path of the CrackLib dictionary. See \*(L"\s-1CONFIGURATION\*(R"\s0 below for
+details on the supported configuration options.
+.PP
\&\fBheimdal-strength\fR then expects the Heimdal password quality check
information on standard input, specifically:
.PP
rejecting the password on standard error and exit with a status of 0. If
some fatal error occurs, it will print that error to standard error and
exit with a non-zero status.
+.SH "CONFIGURATION"
+.IX Header "CONFIGURATION"
+The following \fIkrb5.conf\fR configuration options are supported:
+.IP "minimum_length" 4
+.IX Item "minimum_length"
+If set to a numeric value, passwords with fewer than that number of
+characters will be rejected, independent of any length restrictions in
+CrackLib. Note that this setting does not bypass the minimum length
+requirements in CrackLib itself.
+.IP "password_dictionary" 4
+.IX Item "password_dictionary"
+Specifies the base path to a CrackLib dictionary and enables password
+strength testing using CrackLib. The provided path should be the full
+path to the dictionary files, omitting the trailing \fI*.hwm\fR, \fI*.pwd\fR,
+and \fI*.pwi\fR extensions for the CrackLib dictionary.
+.IP "password_dictionary_cdb" 4
+.IX Item "password_dictionary_cdb"
+Specifies the base path to a \s-1CDB\s0 dictionary and enables \s-1CDB\s0 password
+dictionary lookups. The path must point to a CDB-format database whose
+keys are the known passwords or dictionary words. The values are ignored.
+You can use the \fBcdbmake-wordlist\fR utility to generate the \s-1CDB\s0 database
+from a word list.
+.Sp
+The \s-1CDB\s0 dictionary lookups do not do the complex password mangling that
+CrackLib does. Instead, the password itself will be checked against the
+dictionary, and then variations of the password formed by removing the
+first character, the last character, the first and last characters, the
+first two characters, and the last two characters. If any of these
+strings are found in the \s-1CDB\s0 database, the password will be rejected;
+otherwise, it will be accepted, at least by this check.
+.Sp
+Both a CrackLib dictionary and a \s-1CDB\s0 dictionary may be configured at the
+same time, in which case CrackLib will be run first, followed by the \s-1CDB\s0
+checks.
+.IP "require_ascii_printable" 4
+.IX Item "require_ascii_printable"
+If set to a true boolean value, rejects any password that contains
+non-ASCII characters or \s-1ASCII\s0 control characters. Spaces are allowed;
+tabs are not (at least assuming the \s-1POSIX C\s0 locale). No canonicalization
+or character set is defined for Kerberos passwords in general, so you may
+want to reject non-ASCII characters to avoid interoperability problems
+with computers with different default character sets or Unicode
+normalization forms.
+.IP "require_classes" 4
+.IX Item "require_classes"
+This option allows specification of more complex character class
+requirements. The value of this parameter should be one or more
+whitespace-separated rule. Each rule has the syntax:
+.Sp
+.Vb 1
+\& [<min>\-<max>:]<class>[,<class>...]
+.Ve
+.Sp
+where <class> is one of \f(CW\*(C`upper\*(C'\fR, \f(CW\*(C`lower\*(C'\fR, \f(CW\*(C`digit\*(C'\fR, or \f(CW\*(C`symbol\*(C'\fR. The
+symbol class includes all characters other than alphanumeric characters,
+including space. The listed classes must appear in the password.
+Separate multiple required classes with a comma (and no space).
+.Sp
+The character class checks will be done in whatever locale the plugin or
+password check program is run in, which will normally be the \s-1POSIX C\s0
+locale but may be different depending on local configuration.
+.Sp
+A simple example:
+.Sp
+.Vb 1
+\& require_classes = upper,lower,digit
+.Ve
+.Sp
+This requires all passwords contain at least one uppercase letter, at
+least one lowercase letter, and at least one digit.
+.Sp
+If present, <min> and <max> specify the minimum password length and
+maximum password length to which this rule applies. This allows one to
+specify character class requirements that change with password length.
+So, for example:
+.Sp
+.Vb 1
+\& require_classes = 8\-19:upper,lower 8\-15:digit 8\-11:symbol
+.Ve
+.Sp
+requires all passwords from 8 to 11 characters long contain all four
+character classes, passwords from 12 to 15 characters long contain upper
+and lower case and a digit, and passwords from 16 to 19 characters long
+contain both upper and lower case. Passwords longer than 20 characters
+have no character class restrictions. (This example is probably used in
+conjunction with minimum_length = 8.)
+.IP "require_non_letter" 4
+.IX Item "require_non_letter"
+If set to a true boolean value, the password must contain at least one
+character that is not a letter (uppercase or lowercase) or a space. This
+may be helpful in combination with passphrases; users may choose a stock
+English phrase, and this will force at least some additional complexity.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-\&\fIkadm5\-strength\fR\|(3), \fIkpasswdd\fR\|(8), \fIkrb5.conf\fR\|(5)
+\&\fIcdbmake\-wordlist\fR\|(1), \fIkadm5\-strength\fR\|(3), \fIkpasswdd\fR\|(8), \fIkrb5.conf\fR\|(5)
.PP
The \*(L"Password changing\*(R" section of the Heimdal info documentation
describes the interface that this program implements and how to configure
krb5\-strength package.
.SH "AUTHOR"
.IX Header "AUTHOR"
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
Copyright 2010, 2013 The Board of Trustees of the Leland Stanford Junior
* interface. It uses a krb5.conf parameter to determine the location of its
* dictionary.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2009, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
=for stopwords
-heimdal-strength Heimdal CrackLib krb5.conf krb5-strength Allbery
+heimdal-strength Heimdal CrackLib krb5-strength Allbery CDB
+canonicalization cdbmake-wordlist reproducibly
=head1 NAME
=head1 DESCRIPTION
B<heimdal-strength> is an external password quality check program for
-Heimdal that verifies the strength of a password using an embedded copy of
-CrackLib, with some modifications to increase the aggressiveness of its
-rules. It is normally run via kpasswdd(8) using the Heimdal password
-quality check interface rather than directly.
-
-To use this program, the path to a CrackLib database must be configured in
-krb5.conf via the C<password_dictionary> setting in C<[appdefaults]>. It
-uses the application name C<krb5-strength> when trying to find this
-setting. A typical setting would be:
+Heimdal that verifies the strength of a password. 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 particular
+character classes, or any combination of these tests. It is normally run
+via kpasswdd(8) using the Heimdal password quality check interface rather
+than directly.
+
+To use this program, it must be configured in F<krb5.conf> via settings
+in C<[appdefaults]> for the application name C<krb5-strength>. A typical
+setting would be:
krb5-strength = {
password_dictionary = /usr/local/lib/kadmind/dictionary
}
+which says to check passwords with CrackLib using the given path as the
+base path of the CrackLib dictionary. See L</CONFIGURATION> below for
+details on the supported configuration options.
+
B<heimdal-strength> then expects the Heimdal password quality check
information on standard input, specifically:
some fatal error occurs, it will print that error to standard error and
exit with a non-zero status.
+=head1 CONFIGURATION
+
+The following F<krb5.conf> configuration options are supported:
+
+=over 4
+
+=item minimum_length
+
+If set to a numeric value, passwords with fewer than that number of
+characters will be rejected, independent of any length restrictions in
+CrackLib. Note that this setting does not bypass the minimum length
+requirements in CrackLib itself.
+
+=item password_dictionary
+
+Specifies the base path to a CrackLib dictionary and enables password
+strength testing using CrackLib. The provided path should be the full
+path to the dictionary files, omitting the trailing F<*.hwm>, F<*.pwd>,
+and F<*.pwi> extensions for the CrackLib dictionary.
+
+=item password_dictionary_cdb
+
+Specifies the base path to a CDB dictionary and enables CDB password
+dictionary lookups. The path must point to a CDB-format database whose
+keys are the known passwords or dictionary words. The values are ignored.
+You can use the B<cdbmake-wordlist> utility to generate the CDB database
+from a word list.
+
+The CDB dictionary lookups do not do the complex password mangling that
+CrackLib does. Instead, the password itself will be checked against the
+dictionary, and then variations of the password formed by removing the
+first character, the last character, the first and last characters, the
+first two characters, and the last two characters. If any of these
+strings are found in the CDB database, the password will be rejected;
+otherwise, it will be accepted, at least by this check.
+
+Both a CrackLib dictionary and a CDB dictionary may be configured at the
+same time, in which case CrackLib will be run first, followed by the CDB
+checks.
+
+=item require_ascii_printable
+
+If set to a true boolean value, rejects any password that contains
+non-ASCII characters or ASCII control characters. Spaces are allowed;
+tabs are not (at least assuming the POSIX C locale). No canonicalization
+or character set is defined for Kerberos passwords in general, so you may
+want to reject non-ASCII characters to avoid interoperability problems
+with computers with different default character sets or Unicode
+normalization forms.
+
+=item require_classes
+
+This option allows specification of more complex character class
+requirements. The value of this parameter should be one or more
+whitespace-separated rule. Each rule has the syntax:
+
+ [<min>-<max>:]<class>[,<class>...]
+
+where <class> is one of C<upper>, C<lower>, C<digit>, or C<symbol>. The
+symbol class includes all characters other than alphanumeric characters,
+including space. The listed classes must appear in the password.
+Separate multiple required classes with a comma (and no space).
+
+The character class checks will be done in whatever locale the plugin or
+password check program is run in, which will normally be the POSIX C
+locale but may be different depending on local configuration.
+
+A simple example:
+
+ require_classes = upper,lower,digit
+
+This requires all passwords contain at least one uppercase letter, at
+least one lowercase letter, and at least one digit.
+
+If present, <min> and <max> specify the minimum password length and
+maximum password length to which this rule applies. This allows one to
+specify character class requirements that change with password length.
+So, for example:
+
+ require_classes = 8-19:upper,lower 8-15:digit 8-11:symbol
+
+requires all passwords from 8 to 11 characters long contain all four
+character classes, passwords from 12 to 15 characters long contain upper
+and lower case and a digit, and passwords from 16 to 19 characters long
+contain both upper and lower case. Passwords longer than 20 characters
+have no character class restrictions. (This example is probably used in
+conjunction with minimum_length = 8.)
+
+=item require_non_letter
+
+If set to a true boolean value, the password must contain at least one
+character that is not a letter (uppercase or lowercase) or a space. This
+may be helpful in combination with passphrases; users may choose a stock
+English phrase, and this will force at least some additional complexity.
+
+=back
+
=head1 SEE ALSO
-kadm5-strength(3), kpasswdd(8), krb5.conf(5)
+cdbmake-wordlist(1), kadm5-strength(3), kpasswdd(8), krb5.conf(5)
The "Password changing" section of the Heimdal info documentation
describes the interface that this program implements and how to configure
=head1 AUTHOR
-Russ Allbery <rra@stanford.edu>
+Russ Allbery <eagle@eyrie.org>
=head1 COPYRIGHT AND LICENSE
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
*
* The authors hereby relinquish any claim to any copyright that they may have
* in this work, whether granted under contract or by operation of law or
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2008, 2009, 2010, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
+ * Written by Russ Allbery <eagle@eyrie.org>
* Copyright 2006, 2007, 2008, 2009, 2010, 2013
* The Board of Trustees of the Leland Stanford Junior University
*
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Written by Russ Allbery <rra@stanford.edu>
- * Copyright 2008, 2009, 2010
+ * Written by Russ Allbery <eagle@eyrie.org>
+ * Copyright 2008, 2009, 2010, 2013
* The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
message_log_syslog(int pri, size_t len, const char *fmt, va_list args, int err)
{
char *buffer;
+ int status;
buffer = malloc(len + 1);
if (buffer == NULL) {
(unsigned long) len + 1, __FILE__, __LINE__, strerror(errno));
exit(message_fatal_cleanup ? (*message_fatal_cleanup)() : 1);
}
- vsnprintf(buffer, len + 1, fmt, args);
+ status = vsnprintf(buffer, len + 1, fmt, args);
+ if (status < 0) {
+ warn("failed to format output with vsnprintf in syslog handler");
+ free(buffer);
+ return;
+ }
#ifdef _WIN32
{
HANDLE eventlog;
* The canonical version of this file is maintained in the rra-c-util package,
* which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>.
*
- * Copyright 2012
+ * Copyright 2012, 2013
* The Board of Trustees of the Leland Stanford Junior University
* Copyright (c) 2004, 2005, 2006
* by Internet Systems Consortium, Inc. ("ISC")
void
xmalloc_fail(const char *function, size_t size, const char *file, int line)
{
- sysdie("failed to %s %lu bytes at %s line %d", function,
- (unsigned long) size, file, line);
+ if (size == 0)
+ sysdie("failed to format output with %s at %s line %d", function,
+ file, line);
+ else
+ sysdie("failed to %s %lu bytes at %s line %d", function,
+ (unsigned long) size, file, line);
}
/* Assign to this variable to choose a handler other than the default. */
va_copy(args_copy, args);
status = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
- (*xmalloc_error_handler)("vasprintf", status + 1, file, line);
+ status = (status < 0) ? 0 : status + 1;
+ (*xmalloc_error_handler)("vasprintf", status, file, line);
va_copy(args_copy, args);
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
va_copy(args_copy, args);
status = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
- (*xmalloc_error_handler)("asprintf", status + 1, file, line);
+ status = (status < 0) ? 0 : status + 1;
+ (*xmalloc_error_handler)("asprintf", status, file, line);
va_copy(args_copy, args);
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
va_copy(args_copy, args);
status = vsnprintf(NULL, 0, fmt, args_copy);
va_end(args_copy);
- (*xmalloc_error_handler)("asprintf", status + 1, __FILE__, __LINE__);
+ status = (status < 0) ? 0 : status + 1;
+ (*xmalloc_error_handler)("asprintf", status, __FILE__, __LINE__);
va_copy(args_copy, args);
status = vasprintf(strp, fmt, args_copy);
va_end(args_copy);
__attribute__((__nonnull__, __format__(printf, 2, 3)));
#endif
-/* Failure handler takes the function, the size, the file, and the line. */
+/*
+ * Failure handler takes the function, the size, the file, and the line. The
+ * size will be zero if the failure was due to some failure in snprintf
+ * instead of a memory allocation failure.
+ */
typedef void (*xmalloc_handler_type)(const char *, size_t, const char *, int);
/* The default error handler. */