From 82b142996625d6bf20ee667ce602496cb270fccc Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Wed, 3 Dec 2008 18:48:39 +0000 Subject: [PATCH] - add new applet mkpasswd(1) function old new delta bb_ask - 355 +355 mkpasswd_main - 296 +296 .rodata 121746 121847 +101 packed_usage 24632 24689 +57 static.methods - 21 +21 gmatch 229 248 +19 bb_ask_stdin - 11 +11 applet_names 1949 1958 +9 applet_main 1172 1176 +4 sulogin_main 503 505 +2 applet_nameofs 586 588 +2 sha256_hash 329 327 -2 correct_password 208 206 -2 parse_command 1442 1439 -3 get_cred_or_die 145 141 -4 passwd_main 1054 1044 -10 bb_askpass 348 - -348 ------------------------------------------------------------------------------ (add/remove: 4/1 grow/shrink: 7/5 up/down: 877/-369) Total: 508 bytes --- include/applets.h | 1 + include/libbb.h | 5 +-- include/usage.h | 15 +++++++++ libbb/bb_askpass.c | 12 ++++--- libbb/correct_password.c | 2 +- loginutils/Config.in | 7 ++++ loginutils/Kbuild | 1 + loginutils/mkpasswd.c | 71 ++++++++++++++++++++++++++++++++++++++++ loginutils/passwd.c | 10 +++--- loginutils/sulogin.c | 4 +-- mailutils/mail.c | 4 +-- 11 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 loginutils/mkpasswd.c diff --git a/include/applets.h b/include/applets.h index ad3925577..9c844eeae 100644 --- a/include/applets.h +++ b/include/applets.h @@ -252,6 +252,7 @@ USE_MKFIFO(APPLET(mkfifo, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) //USE_MKE2FS(APPLET_ODDNAME(mkfs.ext3, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext3)) USE_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_minix)) USE_MKNOD(APPLET(mknod, _BB_DIR_BIN, _BB_SUID_NEVER)) +USE_MKPASSWD(APPLET(mkpasswd, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) diff --git a/include/libbb.h b/include/libbb.h index acae93a56..a34e8a1f9 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1021,9 +1021,10 @@ extern int del_loop(const char *device) FAST_FUNC; * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC; - +/* Like bb_ask below, but asks on stdin with no timeout. */ +char *bb_ask_stdin(const char * prompt) FAST_FUNC; //TODO: pass buf pointer or return allocated buf (avoid statics)? -char *bb_askpass(int timeout, const char * prompt) FAST_FUNC; +char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC; int bb_ask_confirmation(void) FAST_FUNC; int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; diff --git a/include/usage.h b/include/usage.h index 000b864d6..a174222be 100644 --- a/include/usage.h +++ b/include/usage.h @@ -2618,6 +2618,21 @@ "$ mknod /dev/fd0 b 2 0\n" \ "$ mknod -m 644 /tmp/pipe p\n" +#define mkpasswd_trivial_usage \ + "[OPTIONS] [PASSWORD]" +#define mkpasswd_full_usage "\n\n" \ + "Crypts the PASSWORD using crypt(3)\n" \ + "\nOptions:" \ + "\n\t-P"USE_GETOPT_LONG(", --password-fd=")"NUM\tread password from fd NUM" \ + "\n\t-s"USE_GETOPT_LONG(", --stdin")"\t\tuse stdin; like -P0" \ + "\n\t-m"USE_GETOPT_LONG(", --method=")"TYPE\tEncryption method TYPE" \ + "\n\t-S"USE_GETOPT_LONG(", --salt=")"SALT\t\tuse SALT" \ + //"\n\t-l"USE_GETOPT_LONG(", --length=")"LEN\tRandom password with length LEN" + +#define mkpasswd_example_usage \ + "$ mkpasswd -m md5\n" \ + "$ mkpasswd -l 12\n" + #define mkswap_trivial_usage \ "DEVICE" #define mkswap_full_usage "\n\n" \ diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index c97649733..c0dcf0c5f 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c @@ -15,7 +15,11 @@ static void askpass_timeout(int UNUSED_PARAM ignore) { } -char* FAST_FUNC bb_askpass(int timeout, const char *prompt) +char* FAST_FUNC bb_ask_stdin(const char *prompt) +{ + return bb_ask(STDIN_FILENO, 0, prompt); +} +char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) { /* Was static char[BIGNUM] */ enum { sizeof_passwd = 128 }; @@ -30,8 +34,8 @@ char* FAST_FUNC bb_askpass(int timeout, const char *prompt) passwd = xmalloc(sizeof_passwd); memset(passwd, 0, sizeof_passwd); - tcgetattr(STDIN_FILENO, &oldtio); - tcflush(STDIN_FILENO, TCIFLUSH); + tcgetattr(fd, &oldtio); + tcflush(fd, TCIFLUSH); tio = oldtio; tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); @@ -52,7 +56,7 @@ char* FAST_FUNC bb_askpass(int timeout, const char *prompt) ret = NULL; /* On timeout or Ctrl-C, read will hopefully be interrupted, * and we return NULL */ - if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) { + if (read(fd, passwd, sizeof_passwd - 1) > 0) { ret = passwd; i = 0; /* Last byte is guaranteed to be 0 diff --git a/libbb/correct_password.c b/libbb/correct_password.c index 255b04870..6301589e6 100644 --- a/libbb/correct_password.c +++ b/libbb/correct_password.c @@ -68,7 +68,7 @@ int FAST_FUNC correct_password(const struct passwd *pw) return 1; fake_it: - unencrypted = bb_askpass(0, "Password: "); + unencrypted = bb_ask_stdin("Password: "); if (!unencrypted) { return 0; } diff --git a/loginutils/Config.in b/loginutils/Config.in index 5f66e8685..6efca7edf 100644 --- a/loginutils/Config.in +++ b/loginutils/Config.in @@ -252,6 +252,13 @@ config CHPASSWD standard input and uses this information to update a group of existing users. +config MKPASSWD + bool "mkpasswd" + default n + help + mkpasswd encrypts the given password with the crypt(3) libc function + using the given salt. + config SU bool "su" default n diff --git a/loginutils/Kbuild b/loginutils/Kbuild index 3d0d777e8..616d97721 100644 --- a/loginutils/Kbuild +++ b/loginutils/Kbuild @@ -11,6 +11,7 @@ lib-$(CONFIG_CRYPTPW) += cryptpw.o lib-$(CONFIG_CHPASSWD) += chpasswd.o lib-$(CONFIG_GETTY) += getty.o lib-$(CONFIG_LOGIN) += login.o +lib-$(CONFIG_MKPASSWD) += mkpasswd.o lib-$(CONFIG_PASSWD) += passwd.o lib-$(CONFIG_SU) += su.o lib-$(CONFIG_SULOGIN) += sulogin.o diff --git a/loginutils/mkpasswd.c b/loginutils/mkpasswd.c new file mode 100644 index 000000000..442738e03 --- /dev/null +++ b/loginutils/mkpasswd.c @@ -0,0 +1,71 @@ +/* vi: set sw=4 ts=4 sts=4: */ +/* + * mkpasswd - Overfeatured front end to crypt(3) + * Copyright (c) 2008 Bernhard Reutner-Fischer + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" + +int mkpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int mkpasswd_main(int argc UNUSED_PARAM, char **argv) +{ + char *chp = NULL, *method = NULL, *salt = NULL; + char *encrypted; + int fd = STDIN_FILENO; + enum { + OPT_P = (1 << 0), + OPT_s = (1 << 1), + OPT_m = (1 << 2), + OPT_S = (1 << 3) + }; + static const char methods[] ALIGN1 = + /*"des\0"*/"md5\0""sha-256\0""sha-512\0"; + enum { TYPE_des, TYPE_md5, TYPE_sha256, TYPE_sha512 }; + unsigned algo = TYPE_des, algobits = 1; +#if ENABLE_GETOPT_LONG + static const char mkpasswd_longopts[] ALIGN1 = + "password-fd\0" Required_argument "P" + "stdin\0" No_argument "s" + "method\0" Required_argument "m" + "salt\0" Required_argument "S" + ; + applet_long_options = mkpasswd_longopts; +#endif + opt_complementary = "?1"; /* at most one non-option argument */ + getopt32(argv, "P:sm:S:", &chp, &method, &salt); + argv += optind; + if (option_mask32 & OPT_P) + fd = xatoi_u(chp); + if (option_mask32 & OPT_m) + algo = index_in_strings(methods, method) + 1; + if (*argv) /* we have a cleartext passwd */ + chp = *argv; + else + chp = bb_ask(fd, 0, "Password: "); + if (!salt) + salt = xmalloc(128); + + if (algo) { + char foo[2]; + foo[0] = foo[2] = '$'; + algobits = 4; + /* MD5 == "$1$", SHA-256 == "$5$", SHA-512 == "$6$" */ + if (algo > 1) { + algo += 3; + algobits = 8; + } + foo[1] = '0' + (algo); + strcpy(salt, foo); + } + /* The opt_complementary adds a bit of additional noise, which is good + but not strictly needed. */ + crypt_make_salt(salt + ((!!algo) * 3), algobits, (int)&opt_complementary); + encrypted = pw_encrypt(chp, salt, 1); + puts(encrypted); + if (ENABLE_FEATURE_CLEAN_UP) { + free(encrypted); + } + return EXIT_SUCCESS; +} diff --git a/loginutils/passwd.c b/loginutils/passwd.c index b156ab5af..e3e74bae7 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c @@ -22,7 +22,7 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) if (myuid && pw->pw_passwd[0]) { char *encrypted; - orig = bb_askpass(0, "Old password:"); /* returns ptr to static */ + orig = bb_ask_stdin("Old password:"); /* returns ptr to static */ if (!orig) goto err_ret; encrypted = pw_encrypt(orig, pw->pw_passwd, 1); /* returns malloced str */ @@ -35,16 +35,16 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo) } if (ENABLE_FEATURE_CLEAN_UP) free(encrypted); } - orig = xstrdup(orig); /* or else bb_askpass() will destroy it */ - newp = bb_askpass(0, "New password:"); /* returns ptr to static */ + orig = xstrdup(orig); /* or else bb_ask_stdin() will destroy it */ + newp = bb_ask_stdin("New password:"); /* returns ptr to static */ if (!newp) goto err_ret; - newp = xstrdup(newp); /* we are going to bb_askpass() again, so save it */ + newp = xstrdup(newp); /* we are going to bb_ask_stdin() again, so save it */ if (ENABLE_FEATURE_PASSWD_WEAK_CHECK && obscure(orig, newp, pw) && myuid) goto err_ret; /* non-root is not allowed to have weak passwd */ - cp = bb_askpass(0, "Retype password:"); + cp = bb_ask_stdin("Retype password:"); if (!cp) goto err_ret; if (strcmp(cp, newp)) { diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 892c43484..4ffefe933 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -51,7 +51,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) /* Clear dangerous stuff, set PATH */ sanitize_env_if_suid(); -// bb_askpass() already handles this +// bb_ask() already handles this // signal(SIGALRM, catchalarm); pwd = getpwuid(0); @@ -77,7 +77,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) int r; /* cp points to a static buffer that is zeroed every time */ - cp = bb_askpass(timeout, + cp = bb_ask(STDIN_FILENO, timeout, "Give root password for system maintenance\n" "(or type Control-D for normal startup):"); diff --git a/mailutils/mail.c b/mailutils/mail.c index ab1304a7f..f30984897 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c @@ -228,8 +228,8 @@ void FAST_FUNC get_cred_or_die(int fd) { // either from TTY if (isatty(fd)) { - G.user = xstrdup(bb_askpass(0, "User: ")); - G.pass = xstrdup(bb_askpass(0, "Password: ")); + G.user = xstrdup(bb_ask_stdin("User: ")); + G.pass = xstrdup(bb_ask_stdin("Password: ")); // or from STDIN } else { FILE *fp = fdopen(fd, "r");