- add new applet mkpasswd(1)
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Wed, 3 Dec 2008 18:48:39 +0000 (18:48 -0000)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Wed, 3 Dec 2008 18:48:39 +0000 (18:48 -0000)
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
include/libbb.h
include/usage.h
libbb/bb_askpass.c
libbb/correct_password.c
loginutils/Config.in
loginutils/Kbuild
loginutils/mkpasswd.c [new file with mode: 0644]
loginutils/passwd.c
loginutils/sulogin.c
mailutils/mail.c

index ad39255..9c844ee 100644 (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_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))
index acae93a..a34e8a1 100644 (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 */
 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;
index 000b864..a174222 100644 (file)
        "$ 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" \
index c976497..c0dcf0c 100644 (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] */
        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
index 255b048..6301589 100644 (file)
@@ -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;
        }
index 5f66e86..6efca7e 100644 (file)
@@ -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
index 3d0d777..616d977 100644 (file)
@@ -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 (file)
index 0000000..442738e
--- /dev/null
@@ -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;
+}
index b156ab5..e3e74ba 100644 (file)
@@ -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)) {
index 892c434..4ffefe9 100644 (file)
@@ -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):");
 
index ab1304a..f309848 100644 (file)
@@ -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");