]> eyrie.org Git - kerberos/krb5-strength.git/blob - plugin/internal.h
First pass at support for character class rules
[kerberos/krb5-strength.git] / plugin / internal.h
1 /*
2  * Prototypes for the kadmin password strength checking plugin.
3  *
4  * Developed by Derrick Brashear and Ken Hornstein of Sine Nomine Associates,
5  *     on behalf of Stanford University
6  * Extensive modifications by Russ Allbery <eagle@eyrie.org>
7  * Copyright 2006, 2007, 2009, 2012, 2013
8  *     The Board of Trustees of the Leland Stanford Junior University
9  *
10  * See LICENSE for licensing terms.
11  */
12
13 #ifndef PLUGIN_INTERNAL_H
14 #define PLUGIN_INTERNAL_H 1
15
16 #include <config.h>
17 #include <portable/krb5.h>
18 #include <portable/macros.h>
19
20 #ifdef HAVE_CDB_H
21 # include <cdb.h>
22 #endif
23 #include <stddef.h>
24
25 #ifdef HAVE_KRB5_PWQUAL_PLUGIN_H
26 # include <krb5/pwqual_plugin.h>
27 #else
28 typedef struct krb5_pwqual_moddata_st *krb5_pwqual_moddata;
29 #endif
30
31 /* Error strings returned (and displayed to the user) for various failures. */
32 #define ERROR_ASCII    "password contains non-ASCII or control characters"
33 #define ERROR_DICT     "password found in list of common passwords"
34 #define ERROR_LETTER   "password is only letters and spaces"
35 #define ERROR_SHORT    "password is too short"
36 #define ERROR_USERNAME "password based on username or principal"
37
38 /*
39  * A character class rule, which consists of a minimum length to which the
40  * rule is applied, a maximum length to which the rule is applied, and a set
41  * of flags for which character classes are required.  The symbol class
42  * includes everything that isn't in one of the other classes, including
43  * space.
44  */
45 struct class_rule {
46     size_t min;
47     size_t max;
48     bool lower;
49     bool upper;
50     bool digit;
51     bool symbol;
52     struct class_rule *next;
53 };
54
55 /* Used to store a list of strings, managed by the sync_vector_* functions. */
56 struct vector {
57     size_t count;
58     size_t allocated;
59     char **strings;
60 };
61
62 /*
63  * MIT Kerberos uses this type as an abstract data type for any data that a
64  * password quality check needs to carry.  Reuse it since then we get type
65  * checking for at least the MIT plugin.
66  */
67 struct krb5_pwqual_moddata_st {
68     long minimum_length;        /* Minimum password length */
69     bool ascii;                 /* Whether to require printable ASCII */
70     bool nonletter;             /* Whether to require a non-letter */
71     struct class_rule *rules;   /* Linked list of character class rules */
72     char *dictionary;           /* Base path to CrackLib dictionary */
73     bool have_cdb;              /* Whether we have a CDB dictionary */
74     int cdb_fd;                 /* File descriptor of CDB dictionary */
75 #ifdef HAVE_CDB_H
76     struct cdb cdb;             /* Open CDB dictionary data */
77 #endif
78 };
79
80 BEGIN_DECLS
81
82 /* Default to a hidden visibility for all internal functions. */
83 #pragma GCC visibility push(hidden)
84
85 /* Initialize the plugin and set up configuration. */
86 krb5_error_code strength_init(krb5_context, const char *dictionary,
87                               krb5_pwqual_moddata *);
88
89 /*
90  * Check a password.  Returns 0 if okay.  On error, sets the Kerberos error
91  * message and returns a Kerberos status code.
92  */
93 krb5_error_code strength_check(krb5_context, krb5_pwqual_moddata,
94                                const char *principal, const char *password);
95
96 /* Free the internal plugin state. */
97 void strength_close(krb5_context, krb5_pwqual_moddata);
98
99 /*
100  * CDB handling.  strength_init_cdb gets the dictionary configuration and sets
101  * up the CDB database, strength_check_cdb checks it, and strength_close_cdb
102  * handles freeing resources.
103  *
104  * If not built with CDB support, provide some stubs for check and close.
105  * init is always a real function, which reports an error if CDB is
106  * requested.
107  */
108 krb5_error_code strength_init_cdb(krb5_context, krb5_pwqual_moddata);
109 #ifdef HAVE_CDB
110 krb5_error_code strength_check_cdb(krb5_context, krb5_pwqual_moddata,
111                                    const char *password);
112 void strength_close_cdb(krb5_context, krb5_pwqual_moddata);
113 #else
114 # define strength_check_cdb(c, d, p) 0
115 # define strength_close_cdb(c, d)    /* empty */
116 #endif
117
118 /*
119  * CrackLib handling.  strength_init_cracklib gets the dictionary
120  * configuration does some sanity checks on it, and strength_check_cracklib
121  * checks the password against CrackLib.
122  */
123 krb5_error_code strength_init_cracklib(krb5_context, krb5_pwqual_moddata,
124                                        const char *dictionary);
125 krb5_error_code strength_check_cracklib(krb5_context, krb5_pwqual_moddata,
126                                         const char *password);
127
128 /* Check whether the password statisfies character class requirements. */
129 krb5_error_code strength_check_classes(krb5_context, krb5_pwqual_moddata,
130                                        const char *password);
131
132 /* Check whether the password is based on the principal in some way. */
133 krb5_error_code strength_check_principal(krb5_context, krb5_pwqual_moddata,
134                                          const char *principal,
135                                          const char *password);
136
137 /*
138  * Manage vectors, which are counted lists of strings.  The functions that
139  * return a boolean return false if memory allocation fails.
140  */
141 struct vector *strength_vector_new(void)
142     __attribute__((__malloc__));
143 bool strength_vector_add(struct vector *, const char *string)
144     __attribute__((__nonnull__));
145 void strength_vector_free(struct vector *);
146
147 /*
148  * vector_split_multi splits on a set of characters.  If the vector argument
149  * is NULL, a new vector is allocated; otherwise, the provided one is reused.
150  * Returns NULL on memory allocation failure, after which the provided vector
151  * may have been modified to only have partial results.
152  *
153  * Empty strings will yield zero-length vectors.  Adjacent delimiters are
154  * treated as a single delimiter by vector_split_multi.  Any leading or
155  * trailing delimiters are ignored, so this function will never create
156  * zero-length strings (similar to the behavior of strtok).
157  */
158 struct vector *strength_vector_split_multi(const char *string,
159                                            const char *seps, struct vector *)
160     __attribute__((__nonnull__(1, 2)));
161
162 /*
163  * Obtain configuration settings from krb5.conf.  These are wrappers around
164  * the krb5_appdefault_* APIs that handle setting the section name, obtaining
165  * the local default realm and using it to find settings, and doing any
166  * necessary conversion.
167  */
168 void strength_config_boolean(krb5_context, const char *, bool *)
169     __attribute__((__nonnull__));
170 krb5_error_code strength_config_list(krb5_context, const char *,
171                                      struct vector **)
172     __attribute__((__nonnull__));
173 void strength_config_number(krb5_context, const char *, long *)
174     __attribute__((__nonnull__));
175 void strength_config_string(krb5_context, const char *, char **)
176     __attribute__((__nonnull__));
177
178 /* Parse the more complex configuration of required character classes. */
179 krb5_error_code strength_config_classes(krb5_context, const char *,
180                                         struct class_rule **)
181     __attribute__((__nonnull__));
182
183 /*
184  * Store a particular password quality error in the Kerberos context.  The
185  * _system variant uses errno for the error code and appends the strerror
186  * results to the message.  All versions return the error code set.
187  */
188 krb5_error_code strength_error_class(krb5_context, const char *format, ...)
189     __attribute__((__nonnull__, __format__(printf, 2, 3)));
190 krb5_error_code strength_error_config(krb5_context, const char *format, ...)
191     __attribute__((__nonnull__, __format__(printf, 2, 3)));
192 krb5_error_code strength_error_dict(krb5_context, const char *format, ...)
193     __attribute__((__nonnull__, __format__(printf, 2, 3)));
194 krb5_error_code strength_error_generic(krb5_context, const char *format, ...)
195     __attribute__((__nonnull__, __format__(printf, 2, 3)));
196 krb5_error_code strength_error_system(krb5_context, const char *format, ...)
197     __attribute__((__nonnull__, __format__(printf, 2, 3)));
198 krb5_error_code strength_error_tooshort(krb5_context, const char *format, ...)
199     __attribute__((__nonnull__, __format__(printf, 2, 3)));
200
201 /* Undo default visibility change. */
202 #pragma GCC visibility pop
203
204 END_DECLS
205
206 #endif /* !PLUGIN_INTERNAL_H */