sulogin: use common password-checking routine.
No binary (build failed)
—
(log yok)
| @@ -1301,7 +1301,8 @@ int sd_listen_fds(void); | |
| #define SETUP_ENV_TO_TMP (1 << 2) | |
| #define SETUP_ENV_NO_CHDIR (1 << 4) | |
| extern void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; | |
| - | extern int correct_password(const struct passwd *pw) FAST_FUNC; |
| + | extern int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; |
| + | extern int ask_and_check_password(const struct passwd *pw) FAST_FUNC; |
| /* Returns a malloced string */ | |
| #if !ENABLE_USE_BB_CRYPT | |
| #define pw_encrypt(clear, salt, cleanup) pw_encrypt(clear, salt) | |
| @@ -31,12 +31,15 @@ | |
| #include "libbb.h" | |
| /* Ask the user for a password. | |
| + | * Return 1 without asking if PW has an empty password. |
| + | * Return -1 on EOF, error while reading input, or timeout. |
| * Return 1 if the user gives the correct password for entry PW, | |
| - | * 0 if not. Return 1 without asking if PW has an empty password. |
| + | * 0 if not. |
| * | |
| - | * NULL pw means "just fake it for login with bad username" */ |
| - | |
| - | int FAST_FUNC correct_password(const struct passwd *pw) |
| + | * NULL pw means "just fake it for login with bad username" |
| + | */ |
| + | int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, |
| + | int timeout, const char *prompt) |
| { | |
| char *unencrypted, *encrypted; | |
| const char *correct; | |
| @@ -65,9 +68,10 @@ int FAST_FUNC correct_password(const struct passwd *pw) | |
| return 1; | |
| fake_it: | |
| - | unencrypted = bb_ask_stdin("Password: "); |
| + | unencrypted = bb_ask(STDIN_FILENO, timeout, prompt); |
| if (!unencrypted) { | |
| - | return 0; |
| + | /* EOF (such as ^D) or error (such as ^C) */ |
| + | return -1; |
| } | |
| encrypted = pw_encrypt(unencrypted, correct, 1); | |
| r = (strcmp(encrypted, correct) == 0); | |
| @@ -75,3 +79,8 @@ int FAST_FUNC correct_password(const struct passwd *pw) | |
| memset(unencrypted, 0, strlen(unencrypted)); | |
| return r; | |
| } | |
| + | |
| + | int FAST_FUNC ask_and_check_password(const struct passwd *pw) |
| + | { |
| + | return ask_and_check_password_extended(pw, 0, "Password: "); |
| + | } |
| @@ -420,7 +420,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |
| * Note that reads (in no-echo mode) trash tty attributes. | |
| * If we get interrupted by SIGALRM, we need to restore attrs. | |
| */ | |
| - | if (correct_password(pw)) |
| + | if (ask_and_check_password(pw) > 0) |
| break; | |
| #endif /* ENABLE_PAM */ | |
| auth_failed: | |
| @@ -93,7 +93,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |
| pw = xgetpwnam(opt_username); | |
| - | if (cur_uid == 0 || correct_password(pw)) { |
| + | if (cur_uid == 0 || ask_and_check_password(pw) > 0) { |
| if (ENABLE_FEATURE_SU_SYSLOG) | |
| syslog(LOG_NOTICE, "%c %s %s:%s", | |
| '+', tty, old_user, opt_username); | |
| @@ -14,24 +14,12 @@ | |
| #include "libbb.h" | |
| #include <syslog.h> | |
| - | //static void catchalarm(int UNUSED_PARAM junk) |
| - | //{ |
| - | // exit(EXIT_FAILURE); |
| - | //} |
| - | |
| - | |
| int sulogin_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |
| int sulogin_main(int argc UNUSED_PARAM, char **argv) | |
| { | |
| - | char *cp; |
| int timeout = 0; | |
| struct passwd *pwd; | |
| const char *shell; | |
| - | #if ENABLE_FEATURE_SHADOWPASSWDS |
| - | /* Using _r function to avoid pulling in static buffers */ |
| - | char buffer[256]; |
| - | struct spwd spw; |
| - | #endif |
| logmode = LOGMODE_BOTH; | |
| openlog(applet_name, 0, LOG_AUTH); | |
| @@ -62,43 +50,24 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) | |
| goto auth_error; | |
| } | |
| - | #if ENABLE_FEATURE_SHADOWPASSWDS |
| - | { |
| - | /* getspnam_r may return 0 yet set result to NULL. |
| - | * At least glibc 2.4 does this. Be extra paranoid here. */ |
| - | struct spwd *result = NULL; |
| - | int r = getspnam_r(pwd->pw_name, &spw, buffer, sizeof(buffer), &result); |
| - | if (r || !result) { |
| - | goto auth_error; |
| - | } |
| - | pwd->pw_passwd = result->sp_pwdp; |
| - | } |
| - | #endif |
| - | |
| while (1) { | |
| - | char *encrypted; |
| int r; | |
| - | /* cp points to a static buffer */ |
| - | cp = bb_ask(STDIN_FILENO, timeout, |
| - | "Give root password for system maintenance\n" |
| - | "(or type Control-D for normal startup):"); |
| - | if (!cp) { |
| + | r = ask_and_check_password_extended(pwd, timeout, |
| + | "Give root password for system maintenance\n" |
| + | "(or type Control-D for normal startup):" |
| + | ); |
| + | if (r < 0) { |
| /* ^D, ^C, timeout, or read error */ | |
| bb_info_msg("Normal startup"); | |
| return 0; | |
| } | |
| - | encrypted = pw_encrypt(cp, pwd->pw_passwd, 1); |
| - | r = strcmp(encrypted, pwd->pw_passwd); |
| - | free(encrypted); |
| - | if (r == 0) { |
| + | if (r > 0) { |
| break; | |
| } | |
| bb_do_delay(LOGIN_FAIL_DELAY); | |
| bb_info_msg("Login incorrect"); | |
| } | |
| - | memset(cp, 0, strlen(cp)); |
| - | // signal(SIGALRM, SIG_DFL); |
| bb_info_msg("System Maintenance Mode"); | |
| @@ -104,7 +104,7 @@ int vlock_main(int argc UNUSED_PARAM, char **argv) | |
| /* "s" if -a, else "": */ "s" + !option_mask32, | |
| pw->pw_name | |
| ); | |
| - | if (correct_password(pw)) { |
| + | if (ask_and_check_password(pw) > 0) { |
| break; | |
| } | |
| bb_do_delay(LOGIN_FAIL_DELAY); | |