- /* Check with one or two characters removed from the start. */
- if (password[0] != '\0') {
- CHECK_PASSWORD(ctx, data, password + 1);
- if (password[1] != '\0')
- CHECK_PASSWORD(ctx, data, password + 2);
+ /* Allocate memory for password variations. */
+ length = strlen(password);
+ variant = malloc(length + 2);
+ if (variant == NULL)
+ return strength_error_system(ctx, "cannot allocate memory");
+
+ /* Check all one-character deletions. */
+ for (i = 0; i < length; i++) {
+ if (i > 0)
+ memcpy(variant, password, i);
+ if (i < length - 1)
+ memcpy(variant + i, password + i + 1, length - i - 1);
+ variant[length - 1] = '\0';
+ CHECK_PASSWORD(ctx, data, variant);
+ }
+
+ /* Check all one-character permutations. */
+ memcpy(variant, password, length + 1);
+ for (p = variant; *p != '\0'; p++)
+ CHECK_PASSWORD_VARIANT(ctx, data, variant, p);
+
+ /* Check all one-character additions. */
+ for (i = 0; i <= length; i++) {
+ if (i > 0)
+ memcpy(variant, password, i);
+ if (i < length)
+ memcpy(variant + i + 1, password + i, length - i);
+ variant[length + 1] = '\0';
+ CHECK_PASSWORD_VARIANT(ctx, data, variant, variant + i);