* 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 2020, 2023 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.
+ * SPDX-License-Identifier: MIT
*/
#include <config.h>
#include <portable/system.h>
#include <errno.h>
+#ifdef HAVE_KADM5_KADM5_PWCHECK_H
+# include <kadm5/kadm5-pwcheck.h>
+#endif
-#include <plugin/api.h>
+#include <plugin/internal.h>
#include <util/macros.h>
/* Skip this entire file if not building with Heimdal. */
#ifdef HAVE_KRB5_REALM
-/* kadm5/kadm5-pwcheck.h isn't always installed by Heimdal. */
-# ifdef HAVE_KADM5_KADM5_PWCHECK_H
-# include <kadm5/kadm5-pwcheck.h>
-# else
-# define KADM5_PASSWD_VERSION_V1 1
-
-typedef int
-(*kadm5_passwd_quality_check_func)(krb5_context context,
- krb5_principal principal,
- krb5_data *password,
- const char *tuning,
- char *message,
- size_t length);
-
-struct kadm5_pw_policy_check_func {
- const char *name;
- kadm5_passwd_quality_check_func func;
-};
-struct kadm5_pw_policy_verifier {
- const char *name;
- int version;
- const char *vendor;
- const struct kadm5_pw_policy_check_func *funcs;
-};
-# endif /* !HAVE_KADM5_PWCHECK_H */
+/*
+ * Write a Kerberos error string to a message buffer, with an optional
+ * prefix.
+ */
+static void
+convert_error(krb5_context ctx, krb5_error_code code, const char *prefix,
+ char *message, size_t length)
+{
+ const char *error;
+
+ error = krb5_get_error_message(ctx, code);
+ if (prefix == NULL)
+ snprintf(message, length, "%s", error);
+ else
+ snprintf(message, length, "%s: %s", prefix, error);
+ krb5_free_error_message(ctx, error);
+}
+
/*
* This is the single check function that we provide. It does the glue
krb5_data *password, const char *tuning UNUSED, char *message,
size_t length)
{
- krb5_pwqual_moddata data;
+ krb5_pwqual_moddata data = NULL;
char *pastring;
char *name = NULL;
krb5_error_code code;
- const char *error;
+ /* Convert the password to a C string. */
pastring = malloc(password->length + 1);
if (pastring == NULL) {
snprintf(message, length, "cannot allocate memory: %s",
}
memcpy(pastring, password->data, password->length);
pastring[password->length] = '\0';
- code = pwcheck_init(ctx, NULL, &data);
+
+ /* Initialize strength checking. */
+ code = strength_init(ctx, NULL, &data);
if (code != 0) {
- error = krb5_get_error_message(ctx, code);
- snprintf(message, length, "cannot initialize strength checking: %s",
- error);
- krb5_free_error_message(ctx, error);
- free(pastring);
- return 1;
+ convert_error(ctx, code, NULL, message, length);
+ goto done;
}
+
+ /* Convert the principal to a string. */
code = krb5_unparse_name(ctx, principal, &name);
if (code != 0) {
- error = krb5_get_error_message(ctx, code);
- snprintf(message, length, "cannot unparse principal name: %s", error);
- krb5_free_error_message(ctx, error);
- free(pastring);
- pwcheck_close(ctx, data);
- return 1;
- }
- code = pwcheck_check(ctx, data, pastring, name);
- if (code != 0) {
- error = krb5_get_error_message(ctx, code);
- snprintf(message, length, "%s", error);
- krb5_free_error_message(ctx, error);
+ convert_error(ctx, code, "cannot unparse principal", message, length);
+ goto done;
}
- krb5_free_unparsed_name(ctx, name);
+
+ /* Do the password strength check. */
+ code = strength_check(ctx, data, name, pastring);
+ if (code != 0)
+ convert_error(ctx, code, NULL, message, length);
+
+done:
+ explicit_bzero(pastring, password->length);
free(pastring);
- pwcheck_close(ctx, data);
+ if (name != NULL)
+ krb5_free_unparsed_name(ctx, name);
+ if (data != NULL)
+ strength_close(ctx, data);
return (code == 0) ? 0 : 1;
}
/* The public symbol that Heimdal looks for. */
+/* clang-format off */
static struct kadm5_pw_policy_check_func functions[] = {
- { "krb5-strength", heimdal_pwcheck },
- { NULL, NULL }
+ {"krb5-strength", heimdal_pwcheck},
+ {NULL, NULL}
};
+extern struct kadm5_pw_policy_verifier kadm5_password_verifier;
struct kadm5_pw_policy_verifier kadm5_password_verifier = {
"krb5-strength",
KADM5_PASSWD_VERSION_V1,
"Russ Allbery",
functions
};
+/* clang-format on */
#endif /* HAVE_KRB5_REALM */