Big apps cleanup (option-parsing, etc)
This is merges the old "rsalz-monolith" branch over to master. The biggest
change is that option parsing switch from cascasding 'else if strcmp("-foo")'
to a utility routine and somethin akin to getopt. Also, an error in the
command line no longer prints the full summary; use -help (or --help :)
for that. There have been many other changes and code-cleanup, see
bullet list below.
Special thanks to Matt for the long and detailed code review.
TEMPORARY:
For now, comment out CRYPTO_mem_leaks() at end of main
Tickets closed:
RT3515: Use 3DES in pkcs12 if built with no-rc2
RT1766: s_client -reconnect and -starttls broke
RT2932: Catch write errors
RT2604: port should be 'unsigned short'
RT2983: total_bytes undeclared #ifdef RENEG
RT1523: Add -nocert to fix output in x509 app
RT3508: Remove unused variable introduced by b09eb24
RT3511: doc fix; req default serial is random
RT1325,2973: Add more extensions to c_rehash
RT2119,3407: Updated to dgst.pod
RT2379: Additional typo fix
RT2693: Extra include of string.h
RT2880: HFS is case-insensitive filenames
RT3246: req command prints version number wrong
Other changes; incompatibilities marked with *:
Add SCSV support
Add -misalign to speed command
Make dhparam, dsaparam, ecparam, x509 output C in proper style
Make some internal ocsp.c functions void
Only display cert usages with -help in verify
Use global bio_err, remove "BIO*err" parameter from functions
For filenames, - always means stdin (or stdout as appropriate)
Add aliases for -des/aes "wrap" ciphers.
*Remove support for IISSGC (server gated crypto)
*The undocumented OCSP -header flag is now "-header name=value"
*Documented the OCSP -header flag
Reviewed-by: Matt Caswell <matt@openssl.org>
This commit is contained in:
230
apps/engine.c
230
apps/engine.c
@@ -1,4 +1,3 @@
|
||||
/* apps/engine.c -*- mode: C; c-file-style: "eay" -*- */
|
||||
/*
|
||||
* Written by Richard Levitte <richard@levitte.org> for the OpenSSL project
|
||||
* 2000.
|
||||
@@ -66,27 +65,26 @@
|
||||
# include <openssl/engine.h>
|
||||
# include <openssl/ssl.h>
|
||||
|
||||
# undef PROG
|
||||
# define PROG engine_main
|
||||
typedef enum OPTION_choice {
|
||||
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
|
||||
OPT_C, OPT_T, OPT_TT, OPT_PRE, OPT_POST,
|
||||
OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV
|
||||
} OPTION_CHOICE;
|
||||
|
||||
static const char *engine_usage[] = {
|
||||
"usage: engine opts [engine ...]\n",
|
||||
" -v[v[v[v]]] - verbose mode, for each engine, list its 'control commands'\n",
|
||||
" -vv will additionally display each command's description\n",
|
||||
" -vvv will also add the input flags for each command\n",
|
||||
" -vvvv will also show internal input flags\n",
|
||||
" -c - for each engine, also list the capabilities\n",
|
||||
" -t[t] - for each engine, check that they are really available\n",
|
||||
" -tt will display error trace for unavailable engines\n",
|
||||
" -pre <cmd> - runs command 'cmd' against the ENGINE before any attempts\n",
|
||||
" to load it (if -t is used)\n",
|
||||
" -post <cmd> - runs command 'cmd' against the ENGINE after loading it\n",
|
||||
" (only used if -t is also provided)\n",
|
||||
" NB: -pre and -post will be applied to all ENGINEs supplied on the command\n",
|
||||
" line, or all supported ENGINEs if none are specified.\n",
|
||||
" Eg. '-pre \"SO_PATH:/lib/libdriver.so\"' calls command \"SO_PATH\" with\n",
|
||||
" argument \"/lib/libdriver.so\".\n",
|
||||
NULL
|
||||
OPTIONS engine_options[] = {
|
||||
{"help", OPT_HELP, '-', "Display this summary"},
|
||||
{"vvvv", OPT_VVVV, '-', "Also show internal input flags"},
|
||||
{"vvv", OPT_VVV, '-', "Also add the input flags for each command"},
|
||||
{"vv", OPT_VV, '-', "Also display each command's description"},
|
||||
{"v", OPT_V, '-', "For each engine, list its 'control commands'"},
|
||||
{"c", OPT_C, '-', "List the capabilities of each engine"},
|
||||
{"t", OPT_T, '-', "Check that each engine is available"},
|
||||
{"tt", OPT_TT, '-', "Display error trace for unavailable engines"},
|
||||
{"pre", OPT_PRE, 's', "Run command against the ENGINE before loading it"},
|
||||
{"post", OPT_POST, 's', "Run command against the ENGINE after loading it"},
|
||||
{OPT_MORE_STR, OPT_EOF, 1,
|
||||
"Commands are like \"SO_PATH:/lib/libdriver.so\""},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static void identity(char *ptr)
|
||||
@@ -124,13 +122,13 @@ static int append_buf(char **buf, const char *s, int *size, int step)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
|
||||
static int util_flags(BIO *out, unsigned int flags, const char *indent)
|
||||
{
|
||||
int started = 0, err = 0;
|
||||
/* Indent before displaying input flags */
|
||||
BIO_printf(bio_out, "%s%s(input flags): ", indent, indent);
|
||||
BIO_printf(out, "%s%s(input flags): ", indent, indent);
|
||||
if (flags == 0) {
|
||||
BIO_printf(bio_out, "<no flags>\n");
|
||||
BIO_printf(out, "<no flags>\n");
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
@@ -138,11 +136,11 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
|
||||
* having it part of all the other flags, even if it really is.
|
||||
*/
|
||||
if (flags & ENGINE_CMD_FLAG_INTERNAL) {
|
||||
BIO_printf(bio_out, "[Internal] ");
|
||||
BIO_printf(out, "[Internal] ");
|
||||
}
|
||||
|
||||
if (flags & ENGINE_CMD_FLAG_NUMERIC) {
|
||||
BIO_printf(bio_out, "NUMERIC");
|
||||
BIO_printf(out, "NUMERIC");
|
||||
started = 1;
|
||||
}
|
||||
/*
|
||||
@@ -153,18 +151,18 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
|
||||
*/
|
||||
if (flags & ENGINE_CMD_FLAG_STRING) {
|
||||
if (started) {
|
||||
BIO_printf(bio_out, "|");
|
||||
BIO_printf(out, "|");
|
||||
err = 1;
|
||||
}
|
||||
BIO_printf(bio_out, "STRING");
|
||||
BIO_printf(out, "STRING");
|
||||
started = 1;
|
||||
}
|
||||
if (flags & ENGINE_CMD_FLAG_NO_INPUT) {
|
||||
if (started) {
|
||||
BIO_printf(bio_out, "|");
|
||||
BIO_printf(out, "|");
|
||||
err = 1;
|
||||
}
|
||||
BIO_printf(bio_out, "NO_INPUT");
|
||||
BIO_printf(out, "NO_INPUT");
|
||||
started = 1;
|
||||
}
|
||||
/* Check for unknown flags */
|
||||
@@ -173,17 +171,16 @@ static int util_flags(BIO *bio_out, unsigned int flags, const char *indent)
|
||||
~ENGINE_CMD_FLAG_NO_INPUT & ~ENGINE_CMD_FLAG_INTERNAL;
|
||||
if (flags) {
|
||||
if (started)
|
||||
BIO_printf(bio_out, "|");
|
||||
BIO_printf(bio_out, "<0x%04X>", flags);
|
||||
BIO_printf(out, "|");
|
||||
BIO_printf(out, "<0x%04X>", flags);
|
||||
}
|
||||
if (err)
|
||||
BIO_printf(bio_out, " <illegal flags!>");
|
||||
BIO_printf(bio_out, "\n");
|
||||
BIO_printf(out, " <illegal flags!>");
|
||||
BIO_printf(out, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int util_verbose(ENGINE *e, int verbose, BIO *bio_out,
|
||||
const char *indent)
|
||||
static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent)
|
||||
{
|
||||
static const int line_wrap = 78;
|
||||
int num;
|
||||
@@ -200,9 +197,9 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out,
|
||||
}
|
||||
|
||||
cmds = sk_OPENSSL_STRING_new_null();
|
||||
|
||||
if (!cmds)
|
||||
goto err;
|
||||
|
||||
do {
|
||||
int len;
|
||||
/* Get the command input flags */
|
||||
@@ -233,26 +230,26 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out,
|
||||
/* Now decide on the output */
|
||||
if (xpos == 0)
|
||||
/* Do an indent */
|
||||
xpos = BIO_puts(bio_out, indent);
|
||||
xpos = BIO_puts(out, indent);
|
||||
else
|
||||
/* Otherwise prepend a ", " */
|
||||
xpos += BIO_printf(bio_out, ", ");
|
||||
xpos += BIO_printf(out, ", ");
|
||||
if (verbose == 1) {
|
||||
/*
|
||||
* We're just listing names, comma-delimited
|
||||
*/
|
||||
if ((xpos > (int)strlen(indent)) &&
|
||||
(xpos + (int)strlen(name) > line_wrap)) {
|
||||
BIO_printf(bio_out, "\n");
|
||||
xpos = BIO_puts(bio_out, indent);
|
||||
BIO_printf(out, "\n");
|
||||
xpos = BIO_puts(out, indent);
|
||||
}
|
||||
xpos += BIO_printf(bio_out, "%s", name);
|
||||
xpos += BIO_printf(out, "%s", name);
|
||||
} else {
|
||||
/* We're listing names plus descriptions */
|
||||
BIO_printf(bio_out, "%s: %s\n", name,
|
||||
BIO_printf(out, "%s: %s\n", name,
|
||||
(desc == NULL) ? "<no description>" : desc);
|
||||
/* ... and sometimes input flags */
|
||||
if ((verbose >= 3) && !util_flags(bio_out, flags, indent))
|
||||
if ((verbose >= 3) && !util_flags(out, flags, indent))
|
||||
goto err;
|
||||
xpos = 0;
|
||||
}
|
||||
@@ -267,7 +264,7 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out,
|
||||
num = ENGINE_ctrl(e, ENGINE_CTRL_GET_NEXT_CMD_TYPE, num, NULL, NULL);
|
||||
} while (num > 0);
|
||||
if (xpos > 0)
|
||||
BIO_printf(bio_out, "\n");
|
||||
BIO_printf(out, "\n");
|
||||
ret = 1;
|
||||
err:
|
||||
if (cmds)
|
||||
@@ -280,12 +277,12 @@ static int util_verbose(ENGINE *e, int verbose, BIO *bio_out,
|
||||
}
|
||||
|
||||
static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
|
||||
BIO *bio_out, const char *indent)
|
||||
BIO *out, const char *indent)
|
||||
{
|
||||
int loop, res, num = sk_OPENSSL_STRING_num(cmds);
|
||||
|
||||
if (num < 0) {
|
||||
BIO_printf(bio_out, "[Error]: internal stack error\n");
|
||||
BIO_printf(out, "[Error]: internal stack error\n");
|
||||
return;
|
||||
}
|
||||
for (loop = 0; loop < num; loop++) {
|
||||
@@ -299,7 +296,7 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
|
||||
res = 0;
|
||||
} else {
|
||||
if ((int)(arg - cmd) > 254) {
|
||||
BIO_printf(bio_out, "[Error]: command name too long\n");
|
||||
BIO_printf(out, "[Error]: command name too long\n");
|
||||
return;
|
||||
}
|
||||
memcpy(buf, cmd, (int)(arg - cmd));
|
||||
@@ -310,90 +307,70 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
|
||||
res = 0;
|
||||
}
|
||||
if (res)
|
||||
BIO_printf(bio_out, "[Success]: %s\n", cmd);
|
||||
BIO_printf(out, "[Success]: %s\n", cmd);
|
||||
else {
|
||||
BIO_printf(bio_out, "[Failure]: %s\n", cmd);
|
||||
ERR_print_errors(bio_out);
|
||||
BIO_printf(out, "[Failure]: %s\n", cmd);
|
||||
ERR_print_errors(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int MAIN(int, char **);
|
||||
|
||||
int MAIN(int argc, char **argv)
|
||||
int engine_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1, i;
|
||||
const char **pp;
|
||||
int verbose = 0, list_cap = 0, test_avail = 0, test_avail_noise = 0;
|
||||
ENGINE *e;
|
||||
STACK_OF(OPENSSL_STRING) *engines = sk_OPENSSL_STRING_new_null();
|
||||
STACK_OF(OPENSSL_STRING) *pre_cmds = sk_OPENSSL_STRING_new_null();
|
||||
STACK_OF(OPENSSL_STRING) *post_cmds = sk_OPENSSL_STRING_new_null();
|
||||
int badops = 1;
|
||||
BIO *bio_out = NULL;
|
||||
BIO *out;
|
||||
const char *indent = " ";
|
||||
OPTION_CHOICE o;
|
||||
char *prog;
|
||||
|
||||
apps_startup();
|
||||
SSL_load_error_strings();
|
||||
|
||||
if (bio_err == NULL)
|
||||
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
|
||||
if (!load_config(bio_err, NULL))
|
||||
out = dup_bio_out();
|
||||
prog = opt_init(argc, argv, engine_options);
|
||||
if (!engines || !pre_cmds || !post_cmds)
|
||||
goto end;
|
||||
bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
# ifdef OPENSSL_SYS_VMS
|
||||
{
|
||||
BIO *tmpbio = BIO_new(BIO_f_linebuffer());
|
||||
bio_out = BIO_push(tmpbio, bio_out);
|
||||
}
|
||||
# endif
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
while (argc >= 1) {
|
||||
if (strncmp(*argv, "-v", 2) == 0) {
|
||||
if (strspn(*argv + 1, "v") < strlen(*argv + 1))
|
||||
goto skip_arg_loop;
|
||||
if ((verbose = strlen(*argv + 1)) > 4)
|
||||
goto skip_arg_loop;
|
||||
} else if (strcmp(*argv, "-c") == 0)
|
||||
while ((o = opt_next()) != OPT_EOF) {
|
||||
switch (o) {
|
||||
case OPT_EOF:
|
||||
case OPT_ERR:
|
||||
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
|
||||
goto end;
|
||||
case OPT_HELP:
|
||||
opt_help(engine_options);
|
||||
ret = 0;
|
||||
goto end;
|
||||
case OPT_VVVV:
|
||||
case OPT_VVV:
|
||||
case OPT_VV:
|
||||
case OPT_V:
|
||||
/* Convert to an integer from one to four. */
|
||||
i = (int)(o - OPT_V) + 1;
|
||||
if (verbose < i)
|
||||
verbose = i;
|
||||
break;
|
||||
case OPT_C:
|
||||
list_cap = 1;
|
||||
else if (strncmp(*argv, "-t", 2) == 0) {
|
||||
test_avail = 1;
|
||||
if (strspn(*argv + 1, "t") < strlen(*argv + 1))
|
||||
goto skip_arg_loop;
|
||||
if ((test_avail_noise = strlen(*argv + 1) - 1) > 1)
|
||||
goto skip_arg_loop;
|
||||
} else if (strcmp(*argv, "-pre") == 0) {
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc == 0)
|
||||
goto skip_arg_loop;
|
||||
sk_OPENSSL_STRING_push(pre_cmds, *argv);
|
||||
} else if (strcmp(*argv, "-post") == 0) {
|
||||
argc--;
|
||||
argv++;
|
||||
if (argc == 0)
|
||||
goto skip_arg_loop;
|
||||
sk_OPENSSL_STRING_push(post_cmds, *argv);
|
||||
} else if ((strncmp(*argv, "-h", 2) == 0) ||
|
||||
(strcmp(*argv, "-?") == 0))
|
||||
goto skip_arg_loop;
|
||||
else
|
||||
sk_OPENSSL_STRING_push(engines, *argv);
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
/* Looks like everything went OK */
|
||||
badops = 0;
|
||||
skip_arg_loop:
|
||||
|
||||
if (badops) {
|
||||
for (pp = engine_usage; (*pp != NULL); pp++)
|
||||
BIO_printf(bio_err, "%s", *pp);
|
||||
goto end;
|
||||
break;
|
||||
case OPT_TT:
|
||||
test_avail_noise++;
|
||||
case OPT_T:
|
||||
test_avail++;
|
||||
break;
|
||||
case OPT_PRE:
|
||||
sk_OPENSSL_STRING_push(pre_cmds, opt_arg());
|
||||
break;
|
||||
case OPT_POST:
|
||||
sk_OPENSSL_STRING_push(post_cmds, opt_arg());
|
||||
break;
|
||||
}
|
||||
}
|
||||
argc = opt_num_rest();
|
||||
argv = opt_rest();
|
||||
for ( ; *argv; argv++)
|
||||
sk_OPENSSL_STRING_push(engines, *argv);
|
||||
|
||||
if (sk_OPENSSL_STRING_num(engines) == 0) {
|
||||
for (e = ENGINE_get_first(); e != NULL; e = ENGINE_get_next(e)) {
|
||||
@@ -408,10 +385,10 @@ int MAIN(int argc, char **argv)
|
||||
/*
|
||||
* Do "id" first, then "name". Easier to auto-parse.
|
||||
*/
|
||||
BIO_printf(bio_out, "(%s) %s\n", id, name);
|
||||
util_do_cmds(e, pre_cmds, bio_out, indent);
|
||||
BIO_printf(out, "(%s) %s\n", id, name);
|
||||
util_do_cmds(e, pre_cmds, out, indent);
|
||||
if (strcmp(ENGINE_get_id(e), id) != 0) {
|
||||
BIO_printf(bio_out, "Loaded: (%s) %s\n",
|
||||
BIO_printf(out, "Loaded: (%s) %s\n",
|
||||
ENGINE_get_id(e), ENGINE_get_name(e));
|
||||
}
|
||||
if (list_cap) {
|
||||
@@ -466,24 +443,24 @@ int MAIN(int argc, char **argv)
|
||||
goto end;
|
||||
skip_pmeths:
|
||||
if (cap_buf && (*cap_buf != '\0'))
|
||||
BIO_printf(bio_out, " [%s]\n", cap_buf);
|
||||
BIO_printf(out, " [%s]\n", cap_buf);
|
||||
|
||||
OPENSSL_free(cap_buf);
|
||||
}
|
||||
if (test_avail) {
|
||||
BIO_printf(bio_out, "%s", indent);
|
||||
BIO_printf(out, "%s", indent);
|
||||
if (ENGINE_init(e)) {
|
||||
BIO_printf(bio_out, "[ available ]\n");
|
||||
util_do_cmds(e, post_cmds, bio_out, indent);
|
||||
BIO_printf(out, "[ available ]\n");
|
||||
util_do_cmds(e, post_cmds, out, indent);
|
||||
ENGINE_finish(e);
|
||||
} else {
|
||||
BIO_printf(bio_out, "[ unavailable ]\n");
|
||||
BIO_printf(out, "[ unavailable ]\n");
|
||||
if (test_avail_noise)
|
||||
ERR_print_errors_fp(stdout);
|
||||
ERR_clear_error();
|
||||
}
|
||||
}
|
||||
if ((verbose > 0) && !util_verbose(e, verbose, bio_out, indent))
|
||||
if ((verbose > 0) && !util_verbose(e, verbose, out, indent))
|
||||
goto end;
|
||||
ENGINE_free(e);
|
||||
} else
|
||||
@@ -497,9 +474,8 @@ int MAIN(int argc, char **argv)
|
||||
sk_OPENSSL_STRING_pop_free(engines, identity);
|
||||
sk_OPENSSL_STRING_pop_free(pre_cmds, identity);
|
||||
sk_OPENSSL_STRING_pop_free(post_cmds, identity);
|
||||
BIO_free_all(bio_out);
|
||||
apps_shutdown();
|
||||
OPENSSL_EXIT(ret);
|
||||
BIO_free_all(out);
|
||||
return (ret);
|
||||
}
|
||||
#else
|
||||
|
||||
|
Reference in New Issue
Block a user