From a81e64575c9f30c0a3af0fd5b558341df433840b Mon Sep 17 00:00:00 2001 From: "Rob Swindell (on Windows 11)" <rob@synchro.net> Date: Thu, 10 Apr 2025 21:43:24 -0700 Subject: [PATCH] Rework part of the "good password" checking algorithm Require that a good password contain a sequence of unique characters (not repeating, incrementing, or decrementing in ASCII code value) of at least half the configured minimum password length. By default, the minimum password length is 4 chars, so this means a sequence of at least 2 unique characters is required. If the minimum password length is increased by the sysop, so is the minimum required unique sequence length. The "PasswordInvalid" text.dat string is printed when passwords are rejected by this criteria. Previously, the following would be rejected by this portion of the algo, this logic has been replaced by the above: - all chars the same (would print the "PasswordInvalid" text.dat string) - first 4 chars are incrementing ("PasswordObvious" string printed) - first 4 chars are decrementing ("PasswordObvious" string printed) but now, a password that starts with "1234" or "abcd" is fine so long as it's longer than that and contains the minimum unique sequence length. This will prevent SBBS from rejecting high quality (e.g. randomly generated or crypto-hashed) passwords that just happen to begin with an incrementing sequence of 4 digits or alpha-characters. --- src/sbbs3/str.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/src/sbbs3/str.cpp b/src/sbbs3/str.cpp index 81d069f449..fff7567b47 100644 --- a/src/sbbs3/str.cpp +++ b/src/sbbs3/str.cpp @@ -849,14 +849,14 @@ bool sbbs_t::inputnstime(time_t *dt) bool sbbs_t::chkpass(char *passwd, user_t* user, bool unique) { char first[128], last[128], sysop[41], sysname[41], *p; - int c, d; char alias[LEN_ALIAS + 1], name[LEN_NAME + 1], handle[LEN_HANDLE + 1]; char pass[LEN_PASS + 1]; SAFECOPY(pass, passwd); strupr(pass); - if (strlen(pass) < cfg.min_pwlen) { + int len = strlen(pass); + if (len < cfg.min_pwlen || len < MIN_PASS_LEN) { bputs(text[PasswordTooShort]); return false; } @@ -864,26 +864,17 @@ bool sbbs_t::chkpass(char *passwd, user_t* user, bool unique) bputs(text[PasswordNotChanged]); return false; } - d = strlen(pass); - for (c = 1; c < d; c++) - if (pass[c] != pass[c - 1]) - break; - if (c == d) { - bputs(text[PasswordInvalid]); - return false; - } - for (c = 0; c < 3; c++) /* check for 1234 and ABCD */ - if (pass[c] != pass[c + 1] + 1) - break; - if (c == 3) { - bputs(text[PasswordObvious]); - return false; + int i; + int run = 0; + for (i = 0; i < (len - 1); ++i) { + if (abs(toupper(pass[i]) - toupper(pass[i + 1])) > 1) { + if (++run >= cfg.min_pwlen / 2) + break; + } else + run = 0; } - for (c = 0; c < 3; c++) /* check for 4321 and ZYXW */ - if (pass[c] != pass[c + 1] - 1) - break; - if (c == 3) { - bputs(text[PasswordObvious]); + if (i >= (len - 1)) { + bputs(text[PasswordInvalid]); return false; } SAFECOPY(name, user->name); -- GitLab