mirror of
https://github.com/shadow-maint/shadow.git
synced 2026-01-26 14:03:17 +00:00
lib/obscure.c: Introduce obscure_get_range
Unify the retrieval of PASS_MIN_LEN and PASS_MAX_LEN for output in passwd and actual checks. Fixes wrong output for minimum password lengths if no such restriction is configured: 5 is printed, 0 is in effect. How to reproduce: 1. Use passwd compiled without PAM support 2. Do not specify PASS_MIN_LEN in login.defs 3. Run passwd as a user and enter your old password, then - you will see that 5 characters are expected - you can just press enter twice Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
This commit is contained in:
parent
deb192fe78
commit
fa88997719
@ -115,17 +115,17 @@ static /*@observer@*//*@null@*/const char *obscure_msg (
|
||||
/*@notnull@*/const char *old,
|
||||
/*@notnull@*/const char *new)
|
||||
{
|
||||
size_t maxlen, oldlen, newlen;
|
||||
int minlen;
|
||||
int maxlen, minlen;
|
||||
size_t oldlen, newlen;
|
||||
char *new1, *old1;
|
||||
const char *msg;
|
||||
const char *result;
|
||||
|
||||
oldlen = strlen (old);
|
||||
newlen = strlen (new);
|
||||
|
||||
minlen = getdef_num ("PASS_MIN_LEN", 0);
|
||||
if (minlen != -1 && newlen < (size_t) minlen) {
|
||||
obscure_get_range(&minlen, &maxlen);
|
||||
|
||||
if (newlen < (size_t) minlen) {
|
||||
return _("too short");
|
||||
}
|
||||
|
||||
@ -141,47 +141,26 @@ static /*@observer@*//*@null@*/const char *obscure_msg (
|
||||
return msg;
|
||||
}
|
||||
|
||||
result = getdef_str ("ENCRYPT_METHOD");
|
||||
if (NULL == result) {
|
||||
if (maxlen == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The traditional crypt() truncates passwords to 8 chars. It is
|
||||
possible to circumvent the above checks by choosing an easy
|
||||
8-char password and adding some random characters to it...
|
||||
Example: "password$%^&*123". So check it again, this time
|
||||
truncated to the maximum length. Idea from npasswd. --marekm */
|
||||
|
||||
if (getdef_bool ("MD5_CRYPT_ENAB")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( streq(result, "MD5")
|
||||
#ifdef USE_SHA_CRYPT
|
||||
|| streq(result, "SHA256")
|
||||
|| streq(result, "SHA512")
|
||||
#endif
|
||||
#ifdef USE_BCRYPT
|
||||
|| streq(result, "BCRYPT")
|
||||
#endif
|
||||
#ifdef USE_YESCRYPT
|
||||
|| streq(result, "YESCRYPT")
|
||||
#endif
|
||||
) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
maxlen = getdef_num ("PASS_MAX_LEN", 8);
|
||||
if ( (oldlen <= maxlen)
|
||||
&& (newlen <= maxlen)) {
|
||||
if ( (oldlen <= (size_t) maxlen)
|
||||
&& (newlen <= (size_t) maxlen)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new1 = xstrdup (new);
|
||||
old1 = xstrdup (old);
|
||||
if (newlen > maxlen)
|
||||
if (newlen > (size_t) maxlen)
|
||||
stpcpy(&new1[maxlen], "");
|
||||
if (oldlen > maxlen)
|
||||
if (oldlen > (size_t) maxlen)
|
||||
stpcpy(&old1[maxlen], "");
|
||||
|
||||
msg = password_check(old1, new1);
|
||||
@ -211,3 +190,50 @@ obscure(const char *old, const char *new)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* obscure_get_range - retrieve min and max password lengths
|
||||
*
|
||||
* Returns minimum and maximum allowed lengths of a password
|
||||
* to pass obscure checks.
|
||||
*/
|
||||
void
|
||||
obscure_get_range(int *minlen, int *maxlen)
|
||||
{
|
||||
int val;
|
||||
const char *method;
|
||||
|
||||
/* Minimum length is 0, even if -1 is configured. */
|
||||
val = getdef_num("PASS_MIN_LEN", 0);
|
||||
*minlen = val == -1 ? 0 : val;
|
||||
|
||||
/* Maximum password length check is optional. */
|
||||
*maxlen = -1;
|
||||
|
||||
if (!getdef_bool("OBSCURE_CHECKS_ENAB")) {
|
||||
return;
|
||||
}
|
||||
|
||||
method = getdef_str ("ENCRYPT_METHOD");
|
||||
if (NULL == method) {
|
||||
if (getdef_bool ("MD5_CRYPT_ENAB")) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ( streq(method, "MD5")
|
||||
#ifdef USE_SHA_CRYPT
|
||||
|| streq(method, "SHA256")
|
||||
|| streq(method, "SHA512")
|
||||
#endif
|
||||
#ifdef USE_BCRYPT
|
||||
|| streq(method, "BCRYPT")
|
||||
#endif
|
||||
#ifdef USE_YESCRYPT
|
||||
|| streq(method, "YESCRYPT")
|
||||
#endif
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
*maxlen = getdef_num ("PASS_MAX_LEN", 8);
|
||||
}
|
||||
|
||||
@ -302,6 +302,7 @@ extern int do_pam_passwd_non_interactive (const char *pam_service,
|
||||
|
||||
/* obscure.c */
|
||||
extern bool obscure (const char *, const char *);
|
||||
extern void obscure_get_range(int *, int *);
|
||||
|
||||
/* pam_pass.c */
|
||||
#ifdef USE_PAM
|
||||
|
||||
33
src/passwd.c
33
src/passwd.c
@ -194,8 +194,6 @@ static int new_password (const struct passwd *pw)
|
||||
int i; /* Counter for retries */
|
||||
int ret;
|
||||
bool warned;
|
||||
int pass_max_len = -1;
|
||||
const char *method;
|
||||
|
||||
/*
|
||||
* Authenticate the user. The user will be prompted for their own
|
||||
@ -245,41 +243,20 @@ static int new_password (const struct passwd *pw)
|
||||
* be optionally tested for strength. The root user can circumvent
|
||||
* tests. This provides an escape for initial login passwords.
|
||||
*/
|
||||
method = getdef_str ("ENCRYPT_METHOD");
|
||||
if (NULL == method) {
|
||||
if (!getdef_bool ("MD5_CRYPT_ENAB")) {
|
||||
pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
|
||||
}
|
||||
} else {
|
||||
if ( streq(method, "MD5")
|
||||
#ifdef USE_SHA_CRYPT
|
||||
|| streq(method, "SHA256")
|
||||
|| streq(method, "SHA512")
|
||||
#endif /* USE_SHA_CRYPT */
|
||||
#ifdef USE_BCRYPT
|
||||
|| streq(method, "BCRYPT")
|
||||
#endif /* USE_BCRYPT*/
|
||||
#ifdef USE_YESCRYPT
|
||||
|| streq(method, "YESCRYPT")
|
||||
#endif /* USE_YESCRYPT*/
|
||||
|
||||
) {
|
||||
pass_max_len = -1;
|
||||
} else {
|
||||
pass_max_len = getdef_num ("PASS_MAX_LEN", 8);
|
||||
}
|
||||
}
|
||||
if (!qflg && !sflg) {
|
||||
int pass_max_len, pass_min_len;
|
||||
|
||||
obscure_get_range(&pass_min_len, &pass_max_len);
|
||||
if (pass_max_len == -1) {
|
||||
(void) printf (_(
|
||||
"Enter the new password (minimum of %d characters)\n"
|
||||
"Please use a combination of upper and lower case letters and numbers.\n"),
|
||||
getdef_num ("PASS_MIN_LEN", 5));
|
||||
pass_min_len);
|
||||
} else {
|
||||
(void) printf (_(
|
||||
"Enter the new password (minimum of %d, maximum of %d characters)\n"
|
||||
"Please use a combination of upper and lower case letters and numbers.\n"),
|
||||
getdef_num ("PASS_MIN_LEN", 5), pass_max_len);
|
||||
pass_min_len, pass_max_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user