//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))
* 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;
"$ 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" \
{
}
-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 };
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);
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
return 1;
fake_it:
- unencrypted = bb_askpass(0, "Password: ");
+ unencrypted = bb_ask_stdin("Password: ");
if (!unencrypted) {
return 0;
}
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
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
--- /dev/null
+/* 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;
+}
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 */
}
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)) {
/* 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);
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):");
{
// 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");