Steve Langasek wrote: > I had a look at the pam_cracklib source, and the logic in the function > similiar() looks quite screwy to me: if you have a 5-character password, and > you try to change it to a 40-character password, the passwords will be > declared "too similar" if 3 of the letters from the old password show up in > the new password? > seems better than the status quo. Andrew, how do you feel about this change? Looking at this 'similiar' function, the logic is indeed very odd. I'd like to suggest it is completely broken. Note, its return value appears to be used as follows: 1 = new and old are too similar 0 = new and old differ enough I'm appending a small program which can be used to test the proposed replacement for this function. I'd be willing to accept stuff that at least is self-consistent and fails _both_ of the following: ./verify_fn rho alpharho ./verify_fn alpharho rho I'd be very happy for others to specify some other constraints. Cheers Andrew
#include <stdio.h> #include <stdlib.h> struct cracklib_options { int diff_ok; }; static int similar(struct cracklib_options *opt, const char *old, const char *new) { int i, j; for (i = j = 0;new[i] && old[i];i++) if (strchr (new, old[i])) j++; if ((j >= opt->diff_ok) || (i >= j * 2)) return 0; return 1; } main(int argc, char **argv) { int retval; const char *msg = NULL, *oldmono, *newmono; static struct cracklib_options crack_opts = { 10 }; if (argc < 3) { fprintf(stderr, "2 words needed: <old> <new> [diff_ok_val]\n"); exit(1); } oldmono = argv[1]; newmono = argv[2]; if (argc > 3) { crack_opts.diff_ok = atoi(argv[3]); } if (!msg && similar(&crack_opts, oldmono, newmono)) { msg = "is too similar to the old one"; } printf("similar looked at old=%s and new=%s, generating\n msg=%s\n", argv[1], argv[2], msg ? msg : "'ok'"); exit(0); }