On Wed, 13 Sep 2023 10:39:43 +0200
Joachim Wiberg <[email protected]> wrote:

> login, on fallback from PAM, or when PAM support is not enabled, checks
> pw->pw_passwd for locked ("!") or passwordless ("*") accounts.  However,
> on systems with shadow passwords the first character will always be "x".
> 
> This patch adds shadow password support from the passwd tool, letting
> the user end up in "Login incorrect" rather than the "login: bad salt"
> case, which could be used by an attacker to guess the state of accounts.
> 
> Signed-off-by: Joachim Wiberg <[email protected]>
> ---
>  loginutils/login.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/loginutils/login.c b/loginutils/login.c
> index b02be2176..0e7f20844 100644
> --- a/loginutils/login.c
> +++ b/loginutils/login.c
> @@ -345,6 +345,11 @@ int login_main(int argc UNUSED_PARAM, char **argv)
>  #endif
>  #if ENABLE_LOGIN_SESSION_AS_CHILD
>       pid_t child_pid;
> +#endif
> +#if ENABLE_FEATURE_SHADOWPASSWDS
> +     /* Using _r function to avoid pulling in static buffers */
> +     struct spwd spw, *result = NULL;
> +     char buffer[256];
>  #endif
>       IF_FEATURE_UTMP(pid_t my_pid;)
>  
> @@ -493,6 +498,16 @@ int login_main(int argc UNUSED_PARAM, char **argv)
>                       goto fake_it;
>               }
>  
> +#if ENABLE_FEATURE_SHADOWPASSWDS
> +             if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), 
> &result)
> +                 || !result || strcmp(result->sp_namp, pw->pw_name)) {
> +                     strcpy(username, "UNKNOWN");
> +                     goto fake_it;
> +             } else {
> +                     pw->pw_passwd = result->sp_pwdp;
> +             }
> +#endif
> +
>               if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*')
>                       goto auth_failed;
>  

Hi,
I wonder if this could be fixed for all applets that use ask_and_check_password 
(login, su, sulogin, vlock) in libbb/correct_password.c. The following patch
is untested (not even compile tested) and only a idea as I haven't touched
C code for long time.

Ciao,
Tito

--- libbb/correct_password.c.orig       2020-01-13 00:23:02.432939000 +0100
+++ libbb/correct_password.c    2023-09-13 23:01:40.804878693 +0200
@@ -42,7 +42,7 @@ static const char *get_passwd(const stru
 {
        const char *pass;
 
-       if (!pw)
+       if (!pw || pw->pw_passwd[0] == '!')
                return "aa"; /* "aa" will never match */
 
        pass = pw->pw_passwd;
@@ -55,7 +55,7 @@ static const char *get_passwd(const stru
                 * At least glibc 2.4 does this. Be extra paranoid here. */
                struct spwd *result = NULL;
                r = getspnam_r(pw->pw_name, &spw, buffer, SHADOW_BUFSIZE, 
&result);
-               pass = (r || !result) ? "aa" : result->sp_pwdp;
+               pass = (r || !result || result->sp_pwdp[0] == '!' || 
(result->sp_pwdp[0] == '*' && !result->sp_pwdp[1])) ? "aa" : result->sp_pwdp;
        }
 #endif
        return pass;

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to