diff options
author | Rich Salz <rsalz@openssl.org> | 2015-04-24 15:26:15 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2015-04-24 15:26:15 -0400 |
commit | 7e1b7485706c2b11091b5fa897fe496a2faa56cc (patch) | |
tree | d008e38fda900d081a2496023625184c5c89a5ff /apps/engine.c | |
parent | 53dd4ddf71ad79a64be934ca19445b1cf560adab (diff) |
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>
Diffstat (limited to 'apps/engine.c')
-rw-r--r-- | apps/engine.c | 232 |
1 files changed, 104 insertions, 128 deletions
diff --git a/apps/engine.c b/apps/engine.c index 53864650ac..7dcc1b0817 100644 --- a/apps/engine.c +++ b/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 - -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 +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; + +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 |