busybox/loginutils/cryptpw.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * cryptpw.c - output a crypt(3)ed password to stdout.
   4 *
   5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
   6 *
   7 * Cooked from passwd.c by Thomas Lundquist <thomasez@zelow.no>
   8 * mkpasswd compatible options added by Bernhard Reutner-Fischer
   9 *
  10 * Licensed under GPLv2, see file LICENSE in this source tree.
  11 */
  12//config:config CRYPTPW
  13//config:       bool "cryptpw (14 kb)"
  14//config:       default y
  15//config:       help
  16//config:       Encrypts the given password with the crypt(3) libc function
  17//config:       using the given salt.
  18//config:
  19//config:config MKPASSWD
  20//config:       bool "mkpasswd (15 kb)"
  21//config:       default y
  22//config:       help
  23//config:       Encrypts the given password with the crypt(3) libc function
  24//config:       using the given salt. Debian has this utility under mkpasswd
  25//config:       name. Busybox provides mkpasswd as an alias for cryptpw.
  26
  27//applet:IF_CRYPTPW( APPLET_NOEXEC(cryptpw,  cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, cryptpw))
  28//                   APPLET_NOEXEC:name      main     location        suid_type     help
  29//applet:IF_MKPASSWD(APPLET_NOEXEC(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, cryptpw))
  30
  31//kbuild:lib-$(CONFIG_CRYPTPW) += cryptpw.o
  32//kbuild:lib-$(CONFIG_MKPASSWD) += cryptpw.o
  33
  34//usage:#define cryptpw_trivial_usage
  35//usage:       "[OPTIONS] [PASSWORD] [SALT]"
  36/* We do support -s, we just don't mention it */
  37//usage:#define cryptpw_full_usage "\n\n"
  38//usage:       "Print crypt(3) hashed PASSWORD\n"
  39//usage:        IF_LONG_OPTS(
  40//usage:     "\n        -P,--password-fd N      Read password from fd N"
  41/* //usage:  "\n        -s,--stdin              Use stdin; like -P0" */
  42//usage:     "\n        -m,--method TYPE        "CRYPT_METHODS_HELP_STR
  43//usage:     "\n        -S,--salt SALT"
  44//usage:        )
  45//usage:        IF_NOT_LONG_OPTS(
  46//usage:     "\n        -P N    Read password from fd N"
  47/* //usage:  "\n        -s      Use stdin; like -P0" */
  48//usage:     "\n        -m TYPE "CRYPT_METHODS_HELP_STR
  49//usage:     "\n        -S SALT"
  50//usage:        )
  51
  52#include "libbb.h"
  53
  54/* Debian has 'mkpasswd' utility, manpage says:
  55
  56NAME
  57    mkpasswd - Overfeatured front end to crypt(3)
  58SYNOPSIS
  59    mkpasswd PASSWORD SALT
  60...
  61OPTIONS
  62-S, --salt=STRING
  63    Use the STRING as salt. It must not  contain  prefixes  such  as
  64    $1$.
  65-R, --rounds=NUMBER
  66    Use NUMBER rounds. This argument is ignored if the method
  67    chosen does not support variable rounds. For the OpenBSD Blowfish
  68    method this is the logarithm of the number of rounds.
  69-m, --method=TYPE
  70    Compute the password using the TYPE method. If TYPE is 'help'
  71    then the available methods are printed.
  72-P, --password-fd=NUM
  73    Read the password from file descriptor NUM instead of using getpass(3).
  74    If the file descriptor is not connected to a tty then
  75    no other message than the hashed password is printed on stdout.
  76-s, --stdin
  77    Like --password-fd=0.
  78ENVIRONMENT
  79    $MKPASSWD_OPTIONS
  80    A list of options which will be evaluated before the ones
  81    specified on the command line.
  82BUGS
  83    This programs suffers of a bad case of featuritis.
  84    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  85
  86Very true...
  87
  88cryptpw was in bbox before this gem, so we retain it, and alias mkpasswd
  89to cryptpw. -a option (alias for -m) came from cryptpw.
  90*/
  91
  92int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  93int cryptpw_main(int argc UNUSED_PARAM, char **argv)
  94{
  95        /* Supports: cryptpw -m sha256 PASS 'rounds=999999999$SALT' */
  96        char salt[MAX_PW_SALT_LEN + sizeof("rounds=999999999$")];
  97        char *salt_ptr;
  98        char *password;
  99        const char *opt_m, *opt_S;
 100        int fd;
 101
 102#if ENABLE_LONG_OPTS
 103        static const char mkpasswd_longopts[] ALIGN1 =
 104                "stdin\0"       No_argument       "s"
 105                "password-fd\0" Required_argument "P"
 106                "salt\0"        Required_argument "S"
 107                "method\0"      Required_argument "m"
 108        ;
 109#endif
 110        fd = STDIN_FILENO;
 111        opt_m = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO;
 112        opt_S = NULL;
 113        /* at most two non-option arguments; -P NUM */
 114        getopt32long(argv, "^" "sP:+S:m:a:" "\0" "?2",
 115                        mkpasswd_longopts,
 116                        &fd, &opt_S, &opt_m, &opt_m
 117        );
 118        argv += optind;
 119
 120        /* have no idea how to handle -s... */
 121
 122        if (argv[0] && !opt_S)
 123                opt_S = argv[1];
 124
 125        salt_ptr = crypt_make_pw_salt(salt, opt_m);
 126        if (opt_S)
 127                /* put user's data after the "$N$" prefix */
 128                safe_strncpy(salt_ptr, opt_S, sizeof(salt) - (sizeof("$N$")-1));
 129
 130        xmove_fd(fd, STDIN_FILENO);
 131
 132        password = argv[0];
 133        if (!password) {
 134                /* Only mkpasswd, and only from tty, prompts.
 135                 * Otherwise it is a plain read. */
 136                password = (ENABLE_MKPASSWD && applet_name[0] == 'm' && isatty(STDIN_FILENO))
 137                        ? bb_ask_noecho_stdin("Password: ")
 138                        : xmalloc_fgetline(stdin)
 139                ;
 140                /* may still be NULL on EOF/error */
 141        }
 142
 143        if (password)
 144                puts(pw_encrypt(password, salt, 1));
 145
 146        return EXIT_SUCCESS;
 147}
 148