]> eyrie.org Git - kerberos/krb5-strength.git/blob - cracklib/fascist.c
Merge commit 'upstream/1.0' into debian
[kerberos/krb5-strength.git] / cracklib / fascist.c
1 /*
2  * This program is copyright Alec Muffett 1993. The author disclaims all
3  * responsibility or liability with respect to it's usage or its effect
4  * upon hardware or computer systems, and maintains copyright as set out
5  * in the "LICENCE" document which accompanies distributions of Crack v4.0
6  * and upwards.
7  */
8
9 /*
10  * Modified as part of the krb5-strength project as follows:
11  *
12  * 2007-03-22  Russ Allbery <rra@stanford.edu>
13  *   - Add four-, five-, and six-character prefix and suffix rules.
14  *   - Longer passwords must contain more different characters, up to 8.
15  *   - Disable GECOS checking (useless for a server).
16  *   - Replace exit(-1) with return when dictionary doesn't exist.
17  *   - Additional system includes for other functions.
18  * 2009-10-14  Russ Allbery <rra@stanford.edu>
19  *   - Add ANSI C protototypes for all functions.
20  *   - Tweaks for const cleanliness.
21  *   - Add parentheses around assignment used for its truth value.
22  *   - Change a variable to unsigned int to avoid gcc warnings.
23  *   - Remove the unused FascistGecos function.
24  */
25
26 static const char vers_id[] = "fascist.c : v2.3p3 Alec Muffett 14 dec 1997";
27
28 #include "packer.h"
29 #include <sys/types.h>
30 #include <pwd.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34
35 #define ISSKIP(x) (isspace(x) || ispunct(x))
36
37 #define MINDIFF 5
38 #define MINLEN 6
39 #define MAXSTEP 4
40 #define MAXMINDIFF 8
41
42 #undef DEBUG
43 #undef DEBUG2
44
45 static const char *r_destructors[] = {
46     ":",                        /* noop - must do this to test raw word. */
47
48 #ifdef DEBUG2
49     (char *) 0,
50 #endif
51
52     "[",                        /* trimming leading/trailing junk */
53     "]",
54     "[[",
55     "]]",
56     "[[[",
57     "]]]", /* 5 for 8 char passwords */ 
58     /* This is for longer passwords, it should be based on length */ 
59     "]]]]", /* 6 for 10 char passwords */ 
60     "[[[[",
61     "]]]]]", /* 7 for 12 char passwords */ 
62     "[[[[[",
63     "]]]]]]", /* 8 for 14 char passwords */ 
64     "[[[[[[",
65
66     "/?p@?p",                   /* purging out punctuation/symbols/junk */
67     "/?s@?s",
68     "/?X@?X",
69
70     /* attempt reverse engineering of password strings */
71
72     "/$s$s",
73     "/$s$s/0s0o",
74     "/$s$s/0s0o/2s2a",
75     "/$s$s/0s0o/2s2a/3s3e",
76     "/$s$s/0s0o/2s2a/3s3e/5s5s",
77     "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i",
78     "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l",
79     "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i/4s4a",
80     "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1i/4s4h",
81     "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l/4s4a",
82     "/$s$s/0s0o/2s2a/3s3e/5s5s/1s1l/4s4h",
83     "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4a",
84     "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4h",
85     "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4a",
86     "/$s$s/0s0o/2s2a/3s3e/5s5s/4s4h",
87     "/$s$s/0s0o/2s2a/3s3e/1s1i",
88     "/$s$s/0s0o/2s2a/3s3e/1s1l",
89     "/$s$s/0s0o/2s2a/3s3e/1s1i/4s4a",
90     "/$s$s/0s0o/2s2a/3s3e/1s1i/4s4h",
91     "/$s$s/0s0o/2s2a/3s3e/1s1l/4s4a",
92     "/$s$s/0s0o/2s2a/3s3e/1s1l/4s4h",
93     "/$s$s/0s0o/2s2a/3s3e/4s4a",
94     "/$s$s/0s0o/2s2a/3s3e/4s4h",
95     "/$s$s/0s0o/2s2a/3s3e/4s4a",
96     "/$s$s/0s0o/2s2a/3s3e/4s4h",
97     "/$s$s/0s0o/2s2a/5s5s",
98     "/$s$s/0s0o/2s2a/5s5s/1s1i",
99     "/$s$s/0s0o/2s2a/5s5s/1s1l",
100     "/$s$s/0s0o/2s2a/5s5s/1s1i/4s4a",
101     "/$s$s/0s0o/2s2a/5s5s/1s1i/4s4h",
102     "/$s$s/0s0o/2s2a/5s5s/1s1l/4s4a",
103     "/$s$s/0s0o/2s2a/5s5s/1s1l/4s4h",
104     "/$s$s/0s0o/2s2a/5s5s/4s4a",
105     "/$s$s/0s0o/2s2a/5s5s/4s4h",
106     "/$s$s/0s0o/2s2a/5s5s/4s4a",
107     "/$s$s/0s0o/2s2a/5s5s/4s4h",
108     "/$s$s/0s0o/2s2a/1s1i",
109     "/$s$s/0s0o/2s2a/1s1l",
110     "/$s$s/0s0o/2s2a/1s1i/4s4a",
111     "/$s$s/0s0o/2s2a/1s1i/4s4h",
112     "/$s$s/0s0o/2s2a/1s1l/4s4a",
113     "/$s$s/0s0o/2s2a/1s1l/4s4h",
114     "/$s$s/0s0o/2s2a/4s4a",
115     "/$s$s/0s0o/2s2a/4s4h",
116     "/$s$s/0s0o/2s2a/4s4a",
117     "/$s$s/0s0o/2s2a/4s4h",
118     "/$s$s/0s0o/3s3e",
119     "/$s$s/0s0o/3s3e/5s5s",
120     "/$s$s/0s0o/3s3e/5s5s/1s1i",
121     "/$s$s/0s0o/3s3e/5s5s/1s1l",
122     "/$s$s/0s0o/3s3e/5s5s/1s1i/4s4a",
123     "/$s$s/0s0o/3s3e/5s5s/1s1i/4s4h",
124     "/$s$s/0s0o/3s3e/5s5s/1s1l/4s4a",
125     "/$s$s/0s0o/3s3e/5s5s/1s1l/4s4h",
126     "/$s$s/0s0o/3s3e/5s5s/4s4a",
127     "/$s$s/0s0o/3s3e/5s5s/4s4h",
128     "/$s$s/0s0o/3s3e/5s5s/4s4a",
129     "/$s$s/0s0o/3s3e/5s5s/4s4h",
130     "/$s$s/0s0o/3s3e/1s1i",
131     "/$s$s/0s0o/3s3e/1s1l",
132     "/$s$s/0s0o/3s3e/1s1i/4s4a",
133     "/$s$s/0s0o/3s3e/1s1i/4s4h",
134     "/$s$s/0s0o/3s3e/1s1l/4s4a",
135     "/$s$s/0s0o/3s3e/1s1l/4s4h",
136     "/$s$s/0s0o/3s3e/4s4a",
137     "/$s$s/0s0o/3s3e/4s4h",
138     "/$s$s/0s0o/3s3e/4s4a",
139     "/$s$s/0s0o/3s3e/4s4h",
140     "/$s$s/0s0o/5s5s",
141     "/$s$s/0s0o/5s5s/1s1i",
142     "/$s$s/0s0o/5s5s/1s1l",
143     "/$s$s/0s0o/5s5s/1s1i/4s4a",
144     "/$s$s/0s0o/5s5s/1s1i/4s4h",
145     "/$s$s/0s0o/5s5s/1s1l/4s4a",
146     "/$s$s/0s0o/5s5s/1s1l/4s4h",
147     "/$s$s/0s0o/5s5s/4s4a",
148     "/$s$s/0s0o/5s5s/4s4h",
149     "/$s$s/0s0o/5s5s/4s4a",
150     "/$s$s/0s0o/5s5s/4s4h",
151     "/$s$s/0s0o/1s1i",
152     "/$s$s/0s0o/1s1l",
153     "/$s$s/0s0o/1s1i/4s4a",
154     "/$s$s/0s0o/1s1i/4s4h",
155     "/$s$s/0s0o/1s1l/4s4a",
156     "/$s$s/0s0o/1s1l/4s4h",
157     "/$s$s/0s0o/4s4a",
158     "/$s$s/0s0o/4s4h",
159     "/$s$s/0s0o/4s4a",
160     "/$s$s/0s0o/4s4h",
161     "/$s$s/2s2a",
162     "/$s$s/2s2a/3s3e",
163     "/$s$s/2s2a/3s3e/5s5s",
164     "/$s$s/2s2a/3s3e/5s5s/1s1i",
165     "/$s$s/2s2a/3s3e/5s5s/1s1l",
166     "/$s$s/2s2a/3s3e/5s5s/1s1i/4s4a",
167     "/$s$s/2s2a/3s3e/5s5s/1s1i/4s4h",
168     "/$s$s/2s2a/3s3e/5s5s/1s1l/4s4a",
169     "/$s$s/2s2a/3s3e/5s5s/1s1l/4s4h",
170     "/$s$s/2s2a/3s3e/5s5s/4s4a",
171     "/$s$s/2s2a/3s3e/5s5s/4s4h",
172     "/$s$s/2s2a/3s3e/5s5s/4s4a",
173     "/$s$s/2s2a/3s3e/5s5s/4s4h",
174     "/$s$s/2s2a/3s3e/1s1i",
175     "/$s$s/2s2a/3s3e/1s1l",
176     "/$s$s/2s2a/3s3e/1s1i/4s4a",
177     "/$s$s/2s2a/3s3e/1s1i/4s4h",
178     "/$s$s/2s2a/3s3e/1s1l/4s4a",
179     "/$s$s/2s2a/3s3e/1s1l/4s4h",
180     "/$s$s/2s2a/3s3e/4s4a",
181     "/$s$s/2s2a/3s3e/4s4h",
182     "/$s$s/2s2a/3s3e/4s4a",
183     "/$s$s/2s2a/3s3e/4s4h",
184     "/$s$s/2s2a/5s5s",
185     "/$s$s/2s2a/5s5s/1s1i",
186     "/$s$s/2s2a/5s5s/1s1l",
187     "/$s$s/2s2a/5s5s/1s1i/4s4a",
188     "/$s$s/2s2a/5s5s/1s1i/4s4h",
189     "/$s$s/2s2a/5s5s/1s1l/4s4a",
190     "/$s$s/2s2a/5s5s/1s1l/4s4h",
191     "/$s$s/2s2a/5s5s/4s4a",
192     "/$s$s/2s2a/5s5s/4s4h",
193     "/$s$s/2s2a/5s5s/4s4a",
194     "/$s$s/2s2a/5s5s/4s4h",
195     "/$s$s/2s2a/1s1i",
196     "/$s$s/2s2a/1s1l",
197     "/$s$s/2s2a/1s1i/4s4a",
198     "/$s$s/2s2a/1s1i/4s4h",
199     "/$s$s/2s2a/1s1l/4s4a",
200     "/$s$s/2s2a/1s1l/4s4h",
201     "/$s$s/2s2a/4s4a",
202     "/$s$s/2s2a/4s4h",
203     "/$s$s/2s2a/4s4a",
204     "/$s$s/2s2a/4s4h",
205     "/$s$s/3s3e",
206     "/$s$s/3s3e/5s5s",
207     "/$s$s/3s3e/5s5s/1s1i",
208     "/$s$s/3s3e/5s5s/1s1l",
209     "/$s$s/3s3e/5s5s/1s1i/4s4a",
210     "/$s$s/3s3e/5s5s/1s1i/4s4h",
211     "/$s$s/3s3e/5s5s/1s1l/4s4a",
212     "/$s$s/3s3e/5s5s/1s1l/4s4h",
213     "/$s$s/3s3e/5s5s/4s4a",
214     "/$s$s/3s3e/5s5s/4s4h",
215     "/$s$s/3s3e/5s5s/4s4a",
216     "/$s$s/3s3e/5s5s/4s4h",
217     "/$s$s/3s3e/1s1i",
218     "/$s$s/3s3e/1s1l",
219     "/$s$s/3s3e/1s1i/4s4a",
220     "/$s$s/3s3e/1s1i/4s4h",
221     "/$s$s/3s3e/1s1l/4s4a",
222     "/$s$s/3s3e/1s1l/4s4h",
223     "/$s$s/3s3e/4s4a",
224     "/$s$s/3s3e/4s4h",
225     "/$s$s/3s3e/4s4a",
226     "/$s$s/3s3e/4s4h",
227     "/$s$s/5s5s",
228     "/$s$s/5s5s/1s1i",
229     "/$s$s/5s5s/1s1l",
230     "/$s$s/5s5s/1s1i/4s4a",
231     "/$s$s/5s5s/1s1i/4s4h",
232     "/$s$s/5s5s/1s1l/4s4a",
233     "/$s$s/5s5s/1s1l/4s4h",
234     "/$s$s/5s5s/4s4a",
235     "/$s$s/5s5s/4s4h",
236     "/$s$s/5s5s/4s4a",
237     "/$s$s/5s5s/4s4h",
238     "/$s$s/1s1i",
239     "/$s$s/1s1l",
240     "/$s$s/1s1i/4s4a",
241     "/$s$s/1s1i/4s4h",
242     "/$s$s/1s1l/4s4a",
243     "/$s$s/1s1l/4s4h",
244     "/$s$s/4s4a",
245     "/$s$s/4s4h",
246     "/$s$s/4s4a",
247     "/$s$s/4s4h",
248     "/0s0o",
249     "/0s0o/2s2a",
250     "/0s0o/2s2a/3s3e",
251     "/0s0o/2s2a/3s3e/5s5s",
252     "/0s0o/2s2a/3s3e/5s5s/1s1i",
253     "/0s0o/2s2a/3s3e/5s5s/1s1l",
254     "/0s0o/2s2a/3s3e/5s5s/1s1i/4s4a",
255     "/0s0o/2s2a/3s3e/5s5s/1s1i/4s4h",
256     "/0s0o/2s2a/3s3e/5s5s/1s1l/4s4a",
257     "/0s0o/2s2a/3s3e/5s5s/1s1l/4s4h",
258     "/0s0o/2s2a/3s3e/5s5s/4s4a",
259     "/0s0o/2s2a/3s3e/5s5s/4s4h",
260     "/0s0o/2s2a/3s3e/5s5s/4s4a",
261     "/0s0o/2s2a/3s3e/5s5s/4s4h",
262     "/0s0o/2s2a/3s3e/1s1i",
263     "/0s0o/2s2a/3s3e/1s1l",
264     "/0s0o/2s2a/3s3e/1s1i/4s4a",
265     "/0s0o/2s2a/3s3e/1s1i/4s4h",
266     "/0s0o/2s2a/3s3e/1s1l/4s4a",
267     "/0s0o/2s2a/3s3e/1s1l/4s4h",
268     "/0s0o/2s2a/3s3e/4s4a",
269     "/0s0o/2s2a/3s3e/4s4h",
270     "/0s0o/2s2a/3s3e/4s4a",
271     "/0s0o/2s2a/3s3e/4s4h",
272     "/0s0o/2s2a/5s5s",
273     "/0s0o/2s2a/5s5s/1s1i",
274     "/0s0o/2s2a/5s5s/1s1l",
275     "/0s0o/2s2a/5s5s/1s1i/4s4a",
276     "/0s0o/2s2a/5s5s/1s1i/4s4h",
277     "/0s0o/2s2a/5s5s/1s1l/4s4a",
278     "/0s0o/2s2a/5s5s/1s1l/4s4h",
279     "/0s0o/2s2a/5s5s/4s4a",
280     "/0s0o/2s2a/5s5s/4s4h",
281     "/0s0o/2s2a/5s5s/4s4a",
282     "/0s0o/2s2a/5s5s/4s4h",
283     "/0s0o/2s2a/1s1i",
284     "/0s0o/2s2a/1s1l",
285     "/0s0o/2s2a/1s1i/4s4a",
286     "/0s0o/2s2a/1s1i/4s4h",
287     "/0s0o/2s2a/1s1l/4s4a",
288     "/0s0o/2s2a/1s1l/4s4h",
289     "/0s0o/2s2a/4s4a",
290     "/0s0o/2s2a/4s4h",
291     "/0s0o/2s2a/4s4a",
292     "/0s0o/2s2a/4s4h",
293     "/0s0o/3s3e",
294     "/0s0o/3s3e/5s5s",
295     "/0s0o/3s3e/5s5s/1s1i",
296     "/0s0o/3s3e/5s5s/1s1l",
297     "/0s0o/3s3e/5s5s/1s1i/4s4a",
298     "/0s0o/3s3e/5s5s/1s1i/4s4h",
299     "/0s0o/3s3e/5s5s/1s1l/4s4a",
300     "/0s0o/3s3e/5s5s/1s1l/4s4h",
301     "/0s0o/3s3e/5s5s/4s4a",
302     "/0s0o/3s3e/5s5s/4s4h",
303     "/0s0o/3s3e/5s5s/4s4a",
304     "/0s0o/3s3e/5s5s/4s4h",
305     "/0s0o/3s3e/1s1i",
306     "/0s0o/3s3e/1s1l",
307     "/0s0o/3s3e/1s1i/4s4a",
308     "/0s0o/3s3e/1s1i/4s4h",
309     "/0s0o/3s3e/1s1l/4s4a",
310     "/0s0o/3s3e/1s1l/4s4h",
311     "/0s0o/3s3e/4s4a",
312     "/0s0o/3s3e/4s4h",
313     "/0s0o/3s3e/4s4a",
314     "/0s0o/3s3e/4s4h",
315     "/0s0o/5s5s",
316     "/0s0o/5s5s/1s1i",
317     "/0s0o/5s5s/1s1l",
318     "/0s0o/5s5s/1s1i/4s4a",
319     "/0s0o/5s5s/1s1i/4s4h",
320     "/0s0o/5s5s/1s1l/4s4a",
321     "/0s0o/5s5s/1s1l/4s4h",
322     "/0s0o/5s5s/4s4a",
323     "/0s0o/5s5s/4s4h",
324     "/0s0o/5s5s/4s4a",
325     "/0s0o/5s5s/4s4h",
326     "/0s0o/1s1i",
327     "/0s0o/1s1l",
328     "/0s0o/1s1i/4s4a",
329     "/0s0o/1s1i/4s4h",
330     "/0s0o/1s1l/4s4a",
331     "/0s0o/1s1l/4s4h",
332     "/0s0o/4s4a",
333     "/0s0o/4s4h",
334     "/0s0o/4s4a",
335     "/0s0o/4s4h",
336     "/2s2a",
337     "/2s2a/3s3e",
338     "/2s2a/3s3e/5s5s",
339     "/2s2a/3s3e/5s5s/1s1i",
340     "/2s2a/3s3e/5s5s/1s1l",
341     "/2s2a/3s3e/5s5s/1s1i/4s4a",
342     "/2s2a/3s3e/5s5s/1s1i/4s4h",
343     "/2s2a/3s3e/5s5s/1s1l/4s4a",
344     "/2s2a/3s3e/5s5s/1s1l/4s4h",
345     "/2s2a/3s3e/5s5s/4s4a",
346     "/2s2a/3s3e/5s5s/4s4h",
347     "/2s2a/3s3e/5s5s/4s4a",
348     "/2s2a/3s3e/5s5s/4s4h",
349     "/2s2a/3s3e/1s1i",
350     "/2s2a/3s3e/1s1l",
351     "/2s2a/3s3e/1s1i/4s4a",
352     "/2s2a/3s3e/1s1i/4s4h",
353     "/2s2a/3s3e/1s1l/4s4a",
354     "/2s2a/3s3e/1s1l/4s4h",
355     "/2s2a/3s3e/4s4a",
356     "/2s2a/3s3e/4s4h",
357     "/2s2a/3s3e/4s4a",
358     "/2s2a/3s3e/4s4h",
359     "/2s2a/5s5s",
360     "/2s2a/5s5s/1s1i",
361     "/2s2a/5s5s/1s1l",
362     "/2s2a/5s5s/1s1i/4s4a",
363     "/2s2a/5s5s/1s1i/4s4h",
364     "/2s2a/5s5s/1s1l/4s4a",
365     "/2s2a/5s5s/1s1l/4s4h",
366     "/2s2a/5s5s/4s4a",
367     "/2s2a/5s5s/4s4h",
368     "/2s2a/5s5s/4s4a",
369     "/2s2a/5s5s/4s4h",
370     "/2s2a/1s1i",
371     "/2s2a/1s1l",
372     "/2s2a/1s1i/4s4a",
373     "/2s2a/1s1i/4s4h",
374     "/2s2a/1s1l/4s4a",
375     "/2s2a/1s1l/4s4h",
376     "/2s2a/4s4a",
377     "/2s2a/4s4h",
378     "/2s2a/4s4a",
379     "/2s2a/4s4h",
380     "/3s3e",
381     "/3s3e/5s5s",
382     "/3s3e/5s5s/1s1i",
383     "/3s3e/5s5s/1s1l",
384     "/3s3e/5s5s/1s1i/4s4a",
385     "/3s3e/5s5s/1s1i/4s4h",
386     "/3s3e/5s5s/1s1l/4s4a",
387     "/3s3e/5s5s/1s1l/4s4h",
388     "/3s3e/5s5s/4s4a",
389     "/3s3e/5s5s/4s4h",
390     "/3s3e/5s5s/4s4a",
391     "/3s3e/5s5s/4s4h",
392     "/3s3e/1s1i",
393     "/3s3e/1s1l",
394     "/3s3e/1s1i/4s4a",
395     "/3s3e/1s1i/4s4h",
396     "/3s3e/1s1l/4s4a",
397     "/3s3e/1s1l/4s4h",
398     "/3s3e/4s4a",
399     "/3s3e/4s4h",
400     "/3s3e/4s4a",
401     "/3s3e/4s4h",
402     "/5s5s",
403     "/5s5s/1s1i",
404     "/5s5s/1s1l",
405     "/5s5s/1s1i/4s4a",
406     "/5s5s/1s1i/4s4h",
407     "/5s5s/1s1l/4s4a",
408     "/5s5s/1s1l/4s4h",
409     "/5s5s/4s4a",
410     "/5s5s/4s4h",
411     "/5s5s/4s4a",
412     "/5s5s/4s4h",
413     "/1s1i",
414     "/1s1l",
415     "/1s1i/4s4a",
416     "/1s1i/4s4h",
417     "/1s1l/4s4a",
418     "/1s1l/4s4h",
419     "/4s4a",
420     "/4s4h",
421     "/4s4a",
422     "/4s4h",
423
424     /* done */
425     (char *) 0
426 };
427
428 static const char *
429 FascistLook(PWDICT *pwp, const char *instring)
430 {
431     int i, pw_len;
432     unsigned int mindiff;
433     char *ptr;
434     char *jptr;
435     char junk[STRINGSIZE];
436     char *password;
437     char rpassword[STRINGSIZE];
438     int32 notfound;
439
440     notfound = PW_WORDS(pwp);
441     /* already truncated if from FascistCheck() */
442     /* but pretend it wasn't ... */
443     strncpy(rpassword, instring, TRUNCSTRINGSIZE);
444     rpassword[TRUNCSTRINGSIZE - 1] = '\0';
445     password = rpassword;
446
447     pw_len = strlen(password); 
448     if (pw_len < 4)
449     {
450         return ("it's WAY too short");
451     }
452
453     if (pw_len < MINLEN)
454     {
455         return ("it is too short");
456     }
457
458     jptr = junk;
459     *jptr = '\0';
460
461     for (i = 0; i < STRINGSIZE && password[i]; i++)
462     {
463         if (!strchr(junk, password[i]))
464         {
465             *(jptr++) = password[i];
466             *jptr = '\0';
467         }
468     }
469
470     /*
471      * mindiff is the number of different characters the password has to
472      * contain.  The original CrackLib always requires five different
473      * characters.  This increases that number up to 8 for passwords longer
474      * than nine characters.
475      */
476     if (pw_len < 2 * MINDIFF)
477     { 
478         mindiff = MINDIFF;
479     } else
480     {
481         if ((pw_len % 2) == 0)
482         {
483             mindiff = (pw_len + 1) / 2;
484         } else
485         {
486             mindiff = pw_len / 2;
487         }
488         mindiff++;
489         if (mindiff > MAXMINDIFF)
490         {
491             mindiff = MAXMINDIFF;
492         }
493     }
494
495     if (strlen(junk) < mindiff)
496     {
497         return ("it does not contain enough DIFFERENT characters");
498     }
499
500     strcpy(password, Lowercase(password));
501
502     Trim(password);
503
504     while (*password && isspace(*password))
505     {
506         password++;
507     }
508
509     if (!*password)
510     {
511         return ("it is all whitespace");
512     }
513
514     i = 0;
515     ptr = password;
516     while (ptr[0] && ptr[1])
517     {
518         if ((ptr[1] == (ptr[0] + 1)) || (ptr[1] == (ptr[0] - 1)))
519         {
520             i++;
521         }
522         ptr++;
523     }
524
525     if (i > MAXSTEP)
526     {
527         return ("it is too simplistic/systematic");
528     }
529
530     if (PMatch("aadddddda", password))  /* smirk */
531     {
532         return ("it looks like a National Insurance number.");
533     }
534
535     /* This is pretty useless for a server. */
536 #ifdef HAVE_GECOS_AVAILABLE
537     if (ptr = FascistGecos(password, getuid()))
538     {
539         return (ptr);
540     }
541 #endif 
542
543     /* it should be safe to use Mangle with its reliance on STRINGSIZE
544        since password cannot be longer than TRUNCSTRINGSIZE;
545        nonetheless this is not an elegant solution */
546
547     for (i = 0; r_destructors[i]; i++)
548     {
549         char *a;
550
551         if (!(a = Mangle(password, r_destructors[i])))
552         {
553             continue;
554         }
555
556 #ifdef DEBUG
557         printf("%-16s (dict)\n", a);
558 #endif
559
560         if (FindPW(pwp, a) != notfound)
561         {
562             return ("it is based on a dictionary word");
563         }
564     }
565
566     strcpy(password, Reverse(password));
567
568     for (i = 0; r_destructors[i]; i++)
569     {
570         char *a;
571
572         if (!(a = Mangle(password, r_destructors[i])))
573         {
574             continue;
575         }
576 #ifdef DEBUG
577         printf("%-16s (reversed dict)\n", a);
578 #endif
579         if (FindPW(pwp, a) != notfound)
580         {
581             return ("it is based on a (reversed) dictionary word");
582         }
583     }
584
585     return ((char *) 0);
586 }
587
588 const char *
589 FascistCheck(const char *password, const char *path)
590 {
591     static char lastpath[STRINGSIZE];
592     static PWDICT *pwp;
593     char pwtrunced[STRINGSIZE];
594
595     /* security problem: assume we may have been given a really long
596        password (buffer attack) and so truncate it to a workable size;
597        try to define workable size as something from which we cannot
598        extend a buffer beyond its limits in the rest of the code */
599
600     strncpy(pwtrunced, password, TRUNCSTRINGSIZE);
601     pwtrunced[TRUNCSTRINGSIZE - 1] = '\0'; /* enforce */
602
603     /* perhaps someone should put something here to check if password
604        is really long and syslog() a message denoting buffer attacks?  */
605
606     if (pwp && strncmp(lastpath, path, STRINGSIZE))
607     {
608         PWClose(pwp);
609         pwp = (PWDICT *)0;
610     }
611
612     if (!pwp)
613     {
614         if (!(pwp = PWOpen(path, "r")))
615         {
616             perror("PWOpen");
617             return "Cannot check password: dictionary unavailable";
618         }
619         strncpy(lastpath, path, STRINGSIZE);
620     }
621
622     return (FascistLook(pwp, pwtrunced));
623 }