2 * Test a password for weaknesses using CrackLib.
4 * Contained here is the interface from the krb5-strength plugin to the
5 * CrackLib library, including initialization and checking of a password
6 * against a CrackLib dictionary.
8 * Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates,
9 * on behalf of Stanford University
10 * Extensive modifications by Russ Allbery <eagle@eyrie.org>
11 * Copyright 2006, 2007, 2009, 2012, 2013
12 * The Board of Trustees of the Leland Stanford Junior University
14 * See LICENSE for licensing terms.
18 #include <portable/system.h>
20 #include <plugin/internal.h>
22 /* When using the embedded CrackLib, we need to provide our own prototype. */
26 extern const char *FascistCheck(const char *password, const char *dict);
31 * Initialize the CrackLib dictionary. Ensure that the dictionary file exists
32 * and is readable and store the path in the module context. Returns 0 on
33 * success, non-zero on failure.
35 * The dictionary file should not include the trailing .pwd extension.
36 * Currently, we don't cope with a NULL dictionary path.
39 strength_init_cracklib(krb5_context ctx, krb5_pwqual_moddata data,
40 const char *dictionary)
46 * Get the dictionary from krb5.conf, and only use the dictionary provided
47 * if krb5.conf configuration is not present. The dictionary passed to
48 * the initialization function is normally set by dict_path in the MIT
49 * Kerberos configuration, and this allows that setting to be used for
50 * other password strength modules while using a different dictionary for
53 strength_config_string(ctx, "password_dictionary", &data->dictionary);
54 if (data->dictionary == NULL && dictionary != NULL) {
55 data->dictionary = strdup(dictionary);
56 if (data->dictionary == NULL)
57 return strength_error_system(ctx, "cannot allocate memory");
60 /* All done if we don't have a dictionary. */
61 if (data->dictionary == NULL)
64 /* Sanity-check the dictionary path. */
65 if (asprintf(&file, "%s.pwd", data->dictionary) < 0)
66 return strength_error_system(ctx, "cannot allocate memory");
67 if (access(file, R_OK) != 0) {
68 code = strength_error_system(ctx, "cannot read dictionary %s", file);
78 * Check a password against CrackLib. Returns 0 on success, non-zero on
79 * failure or if the password is rejected.
82 strength_check_cracklib(krb5_context ctx, krb5_pwqual_moddata data,
87 /* Nothing to do if we don't have a dictionary. */
88 if (data->dictionary == NULL)
91 /* Check the password against CrackLib and return the results. */
92 result = FascistCheck(password, data->dictionary);
94 return strength_error_generic(ctx, "%s", result);