- add new applet mkpasswd(1) function old new delta bb_ask - 355 +355 mkpasswd_main - 296 +296 .rodata 12
No binary (build failed)
—
(log yok)
| @@ -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)) | |
| @@ -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; | |
| @@ -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" \ | |
| @@ -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 | |
| @@ -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; | |
| } | |
| @@ -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 | |
| @@ -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 | |
| @@ -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; |
| + | } |
| @@ -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)) { | |
| @@ -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):"); | |
| @@ -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"); | |