/*
* Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#ifndef OPENSSL_NO_DES
# include <openssl/des.h>
#endif
#include <openssl/md5.h>
#include <openssl/sha.h>
static unsigned const char cov_2char[64] = {
/* from crypto/des/fcrypt.c */
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
static const char ascii_dollar[] = { 0x24, 0x00 };
typedef enum {
passwd_unset = 0,
passwd_crypt,
passwd_md5,
passwd_apr1,
passwd_sha256,
passwd_sha512,
passwd_aixmd5
} passwd_modes;
static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO *out, int quiet, int table,
int reverse, size_t pw_maxlen, passwd_modes mode);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN,
OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN,
OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS passwd_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Read passwords from file"},
{"noverify", OPT_NOVERIFY, '-',
"Never verify when reading password from terminal"},
{"quiet", OPT_QUIET, '-', "No warnings"},
{"table", OPT_TABLE, '-', "Format output as table"},
{"reverse", OPT_REVERSE, '-', "Switch table columns"},
{"salt", OPT_SALT, 's', "Use provided salt"},
{"stdin", OPT_STDIN, '-', "Read passwords from stdin"},
{"6", OPT_6, '-', "SHA512-based password algorithm"},
{"5", OPT_5, '-', "SHA256-based password algorithm"},
{"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"},
{"1", OPT_1, '-', "MD5-based password algorithm"},
{"aixmd5", OPT_AIXMD5, '-', "AIX MD5-based password algorithm"},
#ifndef OPENSSL_NO_DES
{"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
#endif
OPT_R_OPTIONS,
{NULL}
};
int passwd_main(int argc, char **argv)
{
BIO *in = NULL;
char *infile = NULL, *salt = NULL, *passwd = NULL, **passwds = NULL;
char *salt_malloc = NULL, *passwd_malloc = NULL, *prog;
OPTION_CHOICE o;
int in_stdin = 0, pw_source_defined = 0;
#ifndef OPENSSL_NO_UI_CONSOLE
int in_noverify = 0;
#endif
int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
int ret = 1;
passwd_modes mode = passwd_unset;
size_t passwd_malloc_size = 0;
size_t pw_maxlen = 256; /* arbitrary limit, should be enough for most
* passwords */
prog = opt_init(argc, argv, passwd_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
case OPT_EOF:
case OPT_ERR:
opthelp:
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
goto end;
case OPT_HELP:
opt_help(passwd_options);
ret = 0;
goto end;
case OPT_IN:
if (pw_source_defined)
goto opthelp;
infile = opt_arg();
pw_source_defined = 1;
break;
case OPT_NOVERIFY:
#ifndef OPENSSL_NO_UI_CONSOLE