- 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
This commit is contained in:
Bernhard Reutner-Fischer 2008-12-03 18:48:39 +00:00
parent 81c3a1d0b2
commit 82b1429966
11 changed files with 116 additions and 16 deletions

View File

@ -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_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_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_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_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER))
USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER))
USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER))

View File

@ -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 */ * 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; 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)? //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_ask_confirmation(void) FAST_FUNC;
int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;

View File

@ -2618,6 +2618,21 @@
"$ mknod /dev/fd0 b 2 0\n" \ "$ mknod /dev/fd0 b 2 0\n" \
"$ mknod -m 644 /tmp/pipe p\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 \ #define mkswap_trivial_usage \
"DEVICE" "DEVICE"
#define mkswap_full_usage "\n\n" \ #define mkswap_full_usage "\n\n" \

View File

@ -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] */ /* Was static char[BIGNUM] */
enum { sizeof_passwd = 128 }; enum { sizeof_passwd = 128 };
@ -30,8 +34,8 @@ char* FAST_FUNC bb_askpass(int timeout, const char *prompt)
passwd = xmalloc(sizeof_passwd); passwd = xmalloc(sizeof_passwd);
memset(passwd, 0, sizeof_passwd); memset(passwd, 0, sizeof_passwd);
tcgetattr(STDIN_FILENO, &oldtio); tcgetattr(fd, &oldtio);
tcflush(STDIN_FILENO, TCIFLUSH); tcflush(fd, TCIFLUSH);
tio = oldtio; tio = oldtio;
tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
@ -52,7 +56,7 @@ char* FAST_FUNC bb_askpass(int timeout, const char *prompt)
ret = NULL; ret = NULL;
/* On timeout or Ctrl-C, read will hopefully be interrupted, /* On timeout or Ctrl-C, read will hopefully be interrupted,
* and we return NULL */ * and we return NULL */
if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) { if (read(fd, passwd, sizeof_passwd - 1) > 0) {
ret = passwd; ret = passwd;
i = 0; i = 0;
/* Last byte is guaranteed to be 0 /* Last byte is guaranteed to be 0

View File

@ -68,7 +68,7 @@ int FAST_FUNC correct_password(const struct passwd *pw)
return 1; return 1;
fake_it: fake_it:
unencrypted = bb_askpass(0, "Password: "); unencrypted = bb_ask_stdin("Password: ");
if (!unencrypted) { if (!unencrypted) {
return 0; return 0;
} }

View File

@ -252,6 +252,13 @@ config CHPASSWD
standard input and uses this information to update a group of standard input and uses this information to update a group of
existing users. 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 config SU
bool "su" bool "su"
default n default n

View File

@ -11,6 +11,7 @@ lib-$(CONFIG_CRYPTPW) += cryptpw.o
lib-$(CONFIG_CHPASSWD) += chpasswd.o lib-$(CONFIG_CHPASSWD) += chpasswd.o
lib-$(CONFIG_GETTY) += getty.o lib-$(CONFIG_GETTY) += getty.o
lib-$(CONFIG_LOGIN) += login.o lib-$(CONFIG_LOGIN) += login.o
lib-$(CONFIG_MKPASSWD) += mkpasswd.o
lib-$(CONFIG_PASSWD) += passwd.o lib-$(CONFIG_PASSWD) += passwd.o
lib-$(CONFIG_SU) += su.o lib-$(CONFIG_SU) += su.o
lib-$(CONFIG_SULOGIN) += sulogin.o lib-$(CONFIG_SULOGIN) += sulogin.o

71
loginutils/mkpasswd.c Normal file
View File

@ -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;
}

View File

@ -22,7 +22,7 @@ static char* new_password(const struct passwd *pw, uid_t myuid, int algo)
if (myuid && pw->pw_passwd[0]) { if (myuid && pw->pw_passwd[0]) {
char *encrypted; char *encrypted;
orig = bb_askpass(0, "Old password:"); /* returns ptr to static */ orig = bb_ask_stdin("Old password:"); /* returns ptr to static */
if (!orig) if (!orig)
goto err_ret; goto err_ret;
encrypted = pw_encrypt(orig, pw->pw_passwd, 1); /* returns malloced str */ 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); if (ENABLE_FEATURE_CLEAN_UP) free(encrypted);
} }
orig = xstrdup(orig); /* or else bb_askpass() will destroy it */ orig = xstrdup(orig); /* or else bb_ask_stdin() will destroy it */
newp = bb_askpass(0, "New password:"); /* returns ptr to static */ newp = bb_ask_stdin("New password:"); /* returns ptr to static */
if (!newp) if (!newp)
goto err_ret; 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 if (ENABLE_FEATURE_PASSWD_WEAK_CHECK
&& obscure(orig, newp, pw) && myuid) && obscure(orig, newp, pw) && myuid)
goto err_ret; /* non-root is not allowed to have weak passwd */ 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) if (!cp)
goto err_ret; goto err_ret;
if (strcmp(cp, newp)) { if (strcmp(cp, newp)) {

View File

@ -51,7 +51,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
/* Clear dangerous stuff, set PATH */ /* Clear dangerous stuff, set PATH */
sanitize_env_if_suid(); sanitize_env_if_suid();
// bb_askpass() already handles this // bb_ask() already handles this
// signal(SIGALRM, catchalarm); // signal(SIGALRM, catchalarm);
pwd = getpwuid(0); pwd = getpwuid(0);
@ -77,7 +77,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
int r; int r;
/* cp points to a static buffer that is zeroed every time */ /* 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" "Give root password for system maintenance\n"
"(or type Control-D for normal startup):"); "(or type Control-D for normal startup):");

View File

@ -228,8 +228,8 @@ void FAST_FUNC get_cred_or_die(int fd)
{ {
// either from TTY // either from TTY
if (isatty(fd)) { if (isatty(fd)) {
G.user = xstrdup(bb_askpass(0, "User: ")); G.user = xstrdup(bb_ask_stdin("User: "));
G.pass = xstrdup(bb_askpass(0, "Password: ")); G.pass = xstrdup(bb_ask_stdin("Password: "));
// or from STDIN // or from STDIN
} else { } else {
FILE *fp = fdopen(fd, "r"); FILE *fp = fdopen(fd, "r");