diff --git a/src/sbbs3/scfg/scfgsys.c b/src/sbbs3/scfg/scfgsys.c index 4b366f407709a35fec7c9f8e419dfe463392f985..1cfdfea2686c482fecfb2416ebc6d0bcb4e8c9ad 100644 --- a/src/sbbs3/scfg/scfgsys.c +++ b/src/sbbs3/scfg/scfgsys.c @@ -600,7 +600,6 @@ void security_cfg(void) , (!(cfg.uq & UQ_ALIASES) || cfg.sys_login & LOGIN_REALNAME) ? "Yes" : "No"); snprintf(opt[i++], MAX_OPLN, "%-33.33s%s", "Allow Login by User Number" , (cfg.sys_login & LOGIN_USERNUM) ? "Yes" : "No"); - SAFEPRINTF(str, "%s Password" , cfg.sys_misc & SM_PWEDIT && cfg.sys_pwdays ? "Users Must Change" : cfg.sys_pwdays ? "Users Get New Random" : "Users Can Choose"); @@ -613,6 +612,8 @@ void security_cfg(void) if (cfg.sys_misc & SM_PWEDIT) sprintf(tmp + strlen(tmp), ", %u chars minimum", cfg.min_pwlen); snprintf(opt[i++], MAX_OPLN, "%-33.33s%s", str, tmp); + snprintf(opt[i++], MAX_OPLN, "%-33.33s%s", "Demand High Quality Password" + , cfg.hq_password ? "Yes" : "No"); snprintf(opt[i++], MAX_OPLN, "%-33.33s%s", "Always Prompt for Password" , cfg.sys_login & LOGIN_PWPROMPT ? "Yes":"No"); snprintf(opt[i++], MAX_OPLN, "%-33.33s%s", "Display/Log Passwords Locally" @@ -811,6 +812,21 @@ void security_cfg(void) cfg.sys_pwdays = 0; } break; + case __COUNTER__: + i = (cfg.hq_password) ? 0:1; + uifc.helpbuf = + "`Demand High Quality Password:`\n" + "\n" + "If you want users to be required to have a \"high quality\" password\n" + "based on calculated entropy, set this option to `Yes`.\n" + "\n" + "For elevated security, set this option to `Yes`.\n" + ; + i = uifc.list(WIN_MID | WIN_SAV, 0, 10, 0, &i, 0 + , "Require Users to use High Quality/Entropy Passwords", uifcYesNoOpts); + if ((i == 0 && !cfg.hq_password) || (i == 1 && cfg.hq_password)) + cfg.hq_password = !cfg.hq_password; + break; case __COUNTER__: i = cfg.sys_login & LOGIN_PWPROMPT ? 0:1; uifc.helpbuf = diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index 59d342cf422b0cb577887f072538b08b16f17038..e956d6d6375e8658c0de43c6de90ba8cce769dd8 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -486,6 +486,7 @@ typedef struct fevent_t sys_daily; /* Daily event */ fevent_t sys_logon; /* Logon event */ fevent_t sys_logout; /* Logout event */ + bool hq_password; /* Require high quality/entropy user passwords */ uint8_t min_pwlen; uint16_t sys_pwdays; /* Max days between password change */ uint16_t sys_deldays; /* Days to keep deleted users */ diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c index 159486fac2a26cddd8e1933e5ea6a1a4ab6d0ea2..d8a247041057b308fb4c736dbfba1c0c77cbe439 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -127,6 +127,7 @@ bool read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) cfg->max_minutes = iniGetInteger(ini, ROOT_SECTION, "max_minutes", 0); cfg->cdt_per_dollar = (uint32_t)iniGetBytes(ini, ROOT_SECTION, "cdt_per_dollar", 1, 0); cfg->guest_msgscan_init = iniGetInteger(ini, ROOT_SECTION, "guest_msgscan_init", 0); + cfg->hq_password = iniGetBool(ini, ROOT_SECTION, "hq_password", false); cfg->min_pwlen = iniGetInteger(ini, ROOT_SECTION, "min_password_length", 0); if (cfg->min_pwlen < MIN_PASS_LEN) cfg->min_pwlen = MIN_PASS_LEN; diff --git a/src/sbbs3/scfgsave.c b/src/sbbs3/scfgsave.c index 441702bcaf424d68508259b53d1732528c8b03b2..e5b9335d534aa7c17de5cd073fb07688b8565acf 100644 --- a/src/sbbs3/scfgsave.c +++ b/src/sbbs3/scfgsave.c @@ -140,6 +140,7 @@ bool write_main_cfg(scfg_t* cfg) iniSetUInteger(&ini, ROOT_SECTION, "cdt_per_dollar", cfg->cdt_per_dollar, NULL); iniSetBool(&ini, ROOT_SECTION, "new_install", cfg->new_install, NULL); iniSetUInteger(&ini, ROOT_SECTION, "guest_msgscan_init", cfg->guest_msgscan_init, NULL); + iniSetBool(&ini, ROOT_SECTION, "hq_password", cfg->hq_password, NULL); iniSetUInteger(&ini, ROOT_SECTION, "min_password_length", cfg->min_pwlen, NULL); iniSetBytes(&ini, ROOT_SECTION, "max_log_size", 1, cfg->max_log_size, NULL); iniSetUInteger(&ini, ROOT_SECTION, "max_logs_kept", cfg->max_logs_kept, NULL); diff --git a/src/sbbs3/userdat.c b/src/sbbs3/userdat.c index 33770ce0bf188d77efac574dccdbf0476cdcafe6..52d1b555298c76bb681109e8bd6b670a79c6c518 100644 --- a/src/sbbs3/userdat.c +++ b/src/sbbs3/userdat.c @@ -3990,19 +3990,19 @@ bool check_pass(scfg_t* cfg, const char *pass, user_t* user, bool unique, int* r } } - // Require a minimum sequence of unique (non-repeating/increment/decrementing) characters - 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; - } - if (i >= (len - 1)) { - *reason = PasswordInvalid; - return false; + // Require a minimum number of unique (non-repeating/incrementing/decrementing) characters + if (cfg->hq_password) { + int i; + char good[LEN_PASS + 1] = {0}; + int g = 0; + for (i = 0; i < len; ++i) { + if (abs(toupper(pass[i]) - toupper(pass[i + 1])) > 1 && strchr(good, pass[i]) == NULL) + good[g++] = pass[i]; + } + if (g < cfg->min_pwlen) { + *reason = PasswordInvalid; + return false; + } } // Compare proposed password against user properties