summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-11-19 12:09:06 (GMT)
committer Denys Vlasenko <vda.linux@googlemail.com>2013-11-19 12:09:06 (GMT)
commit9c1c605b1a8f34aef347bd9c2e4aea251e556d1b (patch)
tree1854674f7025a8679bd42bd4f056d22a6df891a3
parentf6beef63c64abfc126ea4e73147af29d152f1a9e (diff)
downloadbusybox-9c1c605b1a8f34aef347bd9c2e4aea251e556d1b.tar.gz
busybox-9c1c605b1a8f34aef347bd9c2e4aea251e556d1b.tar.bz2
sulogin: use common password-checking routine.
This needed some extensions correct_passwd() function, which got renamed ask_and_check_password() to better describe what it does. function old new delta ask_and_check_password_extended - 215 +215 ask_and_check_password - 12 +12 vlock_main 394 397 +3 sulogin_main 494 326 -168 correct_password 207 - -207 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 1/1 up/down: 230/-375) Total: -145 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h3
-rw-r--r--libbb/correct_password.c21
-rw-r--r--loginutils/login.c2
-rw-r--r--loginutils/su.c2
-rw-r--r--loginutils/sulogin.c43
-rw-r--r--loginutils/vlock.c2
6 files changed, 26 insertions, 47 deletions
diff --git a/include/libbb.h b/include/libbb.h
index 5827165..e99bb92 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -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)
diff --git a/libbb/correct_password.c b/libbb/correct_password.c
index 7cabd33..d02d0d6 100644
--- a/libbb/correct_password.c
+++ b/libbb/correct_password.c
@@ -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: ");
+}
diff --git a/loginutils/login.c b/loginutils/login.c
index 6ec8dc4..a4b19cc 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -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:
diff --git a/loginutils/su.c b/loginutils/su.c
index 2ec05e1..c51f26f 100644
--- a/loginutils/su.c
+++ b/loginutils/su.c
@@ -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);
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c
index 65e6384..2a29099 100644
--- a/loginutils/sulogin.c
+++ b/loginutils/sulogin.c
@@ -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");
diff --git a/loginutils/vlock.c b/loginutils/vlock.c
index 75af939..44b14e6 100644
--- a/loginutils/vlock.c
+++ b/loginutils/vlock.c
@@ -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);