diff options
author | Martin Willi <martin@strongswan.org> | 2009-09-15 11:49:14 +0200 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-09-15 11:53:46 +0200 |
commit | ae7452e87ce98b1644157d57f4aed247c99050e1 (patch) | |
tree | 039d64cf1762c83e88c4c558ec333d7dd0b4e70b /src/pki | |
parent | 4fdb9f6f74435948143ae60397beb2eb2e02f804 (diff) | |
download | strongswan-ae7452e87ce98b1644157d57f4aed247c99050e1.tar.bz2 strongswan-ae7452e87ce98b1644157d57f4aed247c99050e1.tar.xz |
Handle pki --debug and --options in a generic way for all command
Diffstat (limited to 'src/pki')
-rw-r--r-- | src/pki/command.c | 88 | ||||
-rw-r--r-- | src/pki/command.h | 40 | ||||
-rw-r--r-- | src/pki/commands/gen.c | 16 | ||||
-rw-r--r-- | src/pki/commands/issue.c | 49 | ||||
-rw-r--r-- | src/pki/commands/keyid.c | 24 | ||||
-rw-r--r-- | src/pki/commands/pub.c | 24 | ||||
-rw-r--r-- | src/pki/commands/self.c | 42 | ||||
-rw-r--r-- | src/pki/commands/verify.c | 13 |
8 files changed, 163 insertions, 133 deletions
diff --git a/src/pki/command.c b/src/pki/command.c index 2cf136539..8f5bc14f8 100644 --- a/src/pki/command.c +++ b/src/pki/command.c @@ -14,12 +14,18 @@ */ #include "command.h" +#include "pki.h" - +#define _GNU_SOURCE +#include <getopt.h> #include <stdlib.h> #include <string.h> #include <stdio.h> +#include <library.h> +#include <debug.h> +#include <utils/optionsfrom.h> + /** * Registered commands. */ @@ -40,15 +46,21 @@ static int registered = 0; */ static int help_idx; +static int argc; + +static char **argv; + +static options_t *options; + /** * Global options used by all subcommands */ -struct option command_opts[MAX_COMMANDS > MAX_OPTIONS ?: MAX_OPTIONS]; +static struct option command_opts[MAX_COMMANDS > MAX_OPTIONS ?: MAX_OPTIONS]; /** * Global optstring used by all subcommands */ -char command_optstring[(MAX_COMMANDS > MAX_OPTIONS ?: MAX_OPTIONS) * 3]; +static char command_optstring[(MAX_COMMANDS > MAX_OPTIONS ?: MAX_OPTIONS) * 3]; /** * Build command_opts/command_optstr for the active command @@ -93,11 +105,61 @@ static void build_opts() } /** + * getopt_long wrapper + */ +int command_getopt(char **arg) +{ + int op; + + while (TRUE) + { + op = getopt_long(argc, argv, command_optstring, command_opts, NULL); + switch (op) + { + case '+': + if (!options->from(options, optarg, &argc, &argv, optind)) + { + /* a error value */ + return 255; + } + continue; + case 'v': + dbg_level = atoi(optarg); + continue; + default: + *arg = optarg; + return op; + } + } +} + +/** * Register a command */ void command_register(command_t command) { - cmds[registered++] = command; + int i; + + cmds[registered] = command; + /* append default options, but not to --help */ + if (!active) + { + for (i = 0; i < countof(cmds[registered].options); i++) + { + if (cmds[registered].options[i].name) + { + continue; + } + cmds[registered].options[i++] = (command_option_t) { + "debug", 'v', 1, "set debug level, default: 1" + }; + cmds[registered].options[i++] = (command_option_t) { + "options", '+', 1, "read command line options from file" + }; + break; + } + } + registered++; } /** @@ -159,24 +221,36 @@ static int help(int argc, char *argv[]) } /** + * Dispatch cleanup hook + */ +static void cleanup() +{ + options->destroy(options); +} + +/** * Dispatch commands. */ -int command_dispatch(int argc, char *argv[]) +int command_dispatch(int c, char *v[]) { int op, i; + options = options_create(); + atexit(cleanup); active = help_idx = registered; + argc = c; + argv = v; command_register((command_t){help, 'h', "help", "show usage information"}); build_opts(); - op = getopt_long(argc, argv, command_optstring, command_opts, NULL); + op = getopt_long(c, v, command_optstring, command_opts, NULL); for (i = 0; cmds[i].cmd; i++) { if (cmds[i].op == op) { active = i; build_opts(); - return cmds[i].call(argc, argv); + return cmds[i].call(); } } return command_usage("invalid operation"); diff --git a/src/pki/command.h b/src/pki/command.h index 874bdaa80..fad598c0b 100644 --- a/src/pki/command.h +++ b/src/pki/command.h @@ -21,9 +21,6 @@ #ifndef COMMAND_H_ #define COMMAND_H_ -#define _GNU_SOURCE -#include <getopt.h> - /** * Maximum number of commands. */ @@ -40,14 +37,29 @@ #define MAX_LINES 10 typedef struct command_t command_t; +typedef struct command_option_t command_option_t; typedef enum command_type_t command_type_t; /** + * Option specification + */ +struct command_option_t { + /** long option string of the option */ + char *name; + /** short option character of the option */ + char op; + /** expected argument to option, no/req/opt_argument */ + int arg; + /** description of the option */ + char *desc; +}; + +/** * Command specification. */ struct command_t { /** Function implementing the command */ - int (*call)(int, char*[]); + int (*call)(); /** short option character */ char op; /** long option string */ @@ -57,27 +69,13 @@ struct command_t { /** usage summary of the command */ char *line[MAX_LINES]; /** list of options the command accepts */ - struct { - /** long option string of the option */ - char *name; - /** short option character of the option */ - char op; - /** expected argument to option, no/req/opt_argument */ - int arg; - /** description of the option */ - char *desc; - } options[MAX_OPTIONS]; + command_option_t options[MAX_OPTIONS]; }; /** - * Options of the active command. - */ -extern struct option command_opts[]; - -/** - * Short option string of the active command. + * Get the next option, as with getopt. */ -extern char command_optstring[]; +int command_getopt(char **arg); /** * Register a command. diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c index fcdb50a88..47eb5fae9 100644 --- a/src/pki/commands/gen.c +++ b/src/pki/commands/gen.c @@ -18,29 +18,30 @@ /** * Generate a private key */ -static int gen(int argc, char *argv[]) +static int gen() { key_encoding_type_t form = KEY_PRIV_ASN1_DER; key_type_t type = KEY_RSA; u_int size = 0; private_key_t *key; chunk_t encoding; + char *arg; while (TRUE) { - switch (getopt_long(argc, argv, command_optstring, command_opts, NULL)) + switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); case 'v': - dbg_level = atoi(optarg); + dbg_level = atoi(arg); continue; case 't': - if (streq(optarg, "rsa")) + if (streq(arg, "rsa")) { type = KEY_RSA; } - else if (streq(optarg, "ecdsa")) + else if (streq(arg, "ecdsa")) { type = KEY_ECDSA; } @@ -50,13 +51,13 @@ static int gen(int argc, char *argv[]) } continue; case 'o': - if (!get_form(optarg, &form, FALSE)) + if (!get_form(arg, &form, FALSE)) { return command_usage("invalid key output format"); } continue; case 's': - size = atoi(optarg); + size = atoi(arg); if (!size) { return command_usage("invalid key size"); @@ -121,7 +122,6 @@ static void __attribute__ ((constructor))reg() {"type", 't', 1, "type of key, default: rsa"}, {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"}, {"outform", 'f', 1, "encoding of generated private key"}, - {"debug", 'v', 1, "set debug level, default: 1"}, } }); } diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c index d62de39a4..3e1835da2 100644 --- a/src/pki/commands/issue.c +++ b/src/pki/commands/issue.c @@ -19,7 +19,6 @@ #include <debug.h> #include <utils/linked_list.h> -#include <utils/optionsfrom.h> #include <credentials/certificates/certificate.h> #include <credentials/certificates/x509.h> #include <credentials/certificates/pkcs10.h> @@ -27,7 +26,7 @@ /** * Issue a certificate using a CA certificate and key */ -static int issue(int argc, char *argv[]) +static int issue() { hash_algorithm_t digest = HASH_SHA1; certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL; @@ -44,42 +43,31 @@ static int issue(int argc, char *argv[]) time_t not_before, not_after; x509_flag_t flags = 0; x509_t *x509; - options_t *options; + char *arg; - options = options_create(); san = linked_list_create(); cdps = linked_list_create(); ocsp = linked_list_create(); while (TRUE) { - switch (getopt_long(argc, argv, command_optstring, command_opts, NULL)) + switch (command_getopt(&arg)) { case 'h': goto usage; - case 'v': - dbg_level = atoi(optarg); - continue; - case '+': - if (!options->from(options, optarg, &argc, &argv, optind)) - { - error = "invalid options file"; - goto usage; - } - continue; case 't': - if (streq(optarg, "pkcs10")) + if (streq(arg, "pkcs10")) { pkcs10 = TRUE; } - else if (!streq(optarg, "pub")) + else if (!streq(arg, "pub")) { error = "invalid input type"; goto usage; } continue; case 'g': - digest = get_digest(optarg); + digest = get_digest(arg); if (digest == HASH_UNKNOWN) { error = "invalid --digest type"; @@ -87,22 +75,22 @@ static int issue(int argc, char *argv[]) } continue; case 'i': - file = optarg; + file = arg; continue; case 'c': - cacert = optarg; + cacert = arg; continue; case 'k': - cakey = optarg; + cakey = arg; continue; case 'd': - dn = optarg; + dn = arg; continue; case 'a': - san->insert_last(san, identification_create_from_string(optarg)); + san->insert_last(san, identification_create_from_string(arg)); continue; case 'l': - lifetime = atoi(optarg); + lifetime = atoi(arg); if (!lifetime) { error = "invalid --lifetime value"; @@ -110,16 +98,16 @@ static int issue(int argc, char *argv[]) } continue; case 's': - hex = optarg; + hex = arg; continue; case 'b': flags |= X509_CA; continue; case 'u': - cdps->insert_last(cdps, optarg); + cdps->insert_last(cdps, arg); continue; case 'o': - ocsp->insert_last(ocsp, optarg); + ocsp->insert_last(ocsp, arg); continue; case EOF: break; @@ -311,7 +299,6 @@ end: san->destroy_offset(san, offsetof(identification_t, destroy)); cdps->destroy(cdps); ocsp->destroy(ocsp); - options->destroy(options); free(encoding.ptr); free(serial.ptr); @@ -326,7 +313,6 @@ usage: san->destroy_offset(san, offsetof(identification_t, destroy)); cdps->destroy(cdps); ocsp->destroy(ocsp); - options->destroy(options); return command_usage(error); } @@ -341,8 +327,7 @@ static void __attribute__ ((constructor))reg() {"[--in file] [--type pub|pkcs10]", " --cacert file --cakey file --dn subject-dn [--san subjectAltName]+", "[--lifetime days] [--serial hex] [--ca] [--crl uri]+ [--ocsp uri]+", - "[--digest md5|sha1|sha224|sha256|sha384|sha512]", - "[--options file]"}, + "[--digest md5|sha1|sha224|sha256|sha384|sha512]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "public key/request file to issue, default: stdin"}, @@ -357,8 +342,6 @@ static void __attribute__ ((constructor))reg() {"crl", 'u', 1, "CRL distribution point URI to include"}, {"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"}, {"digest", 'g', 1, "digest for signature creation, default: sha1"}, - {"debug", 'v', 1, "set debug level, default: 1"}, - {"options", '+', 1, "read command line options from file"}, } }); } diff --git a/src/pki/commands/keyid.c b/src/pki/commands/keyid.c index b856a06e3..c15c1193e 100644 --- a/src/pki/commands/keyid.c +++ b/src/pki/commands/keyid.c @@ -21,7 +21,7 @@ /** * Calculate the keyid of a key/certificate */ -static int keyid(int argc, char *argv[]) +static int keyid() { credential_type_t type = CRED_PRIVATE_KEY; int subtype = KEY_RSA; @@ -31,38 +31,36 @@ static int keyid(int argc, char *argv[]) char *file = NULL; void *cred; chunk_t id; + char *arg; while (TRUE) { - switch (getopt_long(argc, argv, command_optstring, command_opts, NULL)) + switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); - case 'v': - dbg_level = atoi(optarg); - continue; case 't': - if (streq(optarg, "rsa-priv")) + if (streq(arg, "rsa-priv")) { type = CRED_PRIVATE_KEY; subtype = KEY_RSA; } - else if (streq(optarg, "ecdsa-priv")) + else if (streq(arg, "ecdsa-priv")) { type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } - else if (streq(optarg, "pub")) + else if (streq(arg, "pub")) { type = CRED_PUBLIC_KEY; subtype = KEY_ANY; } - else if (streq(optarg, "pkcs10")) + else if (streq(arg, "pkcs10")) { type = CRED_CERTIFICATE; subtype = CERT_PKCS10_REQUEST; } - else if (streq(optarg, "x509")) + else if (streq(arg, "x509")) { type = CRED_CERTIFICATE; subtype = CERT_X509; @@ -73,7 +71,7 @@ static int keyid(int argc, char *argv[]) } continue; case 'i': - file = optarg; + file = arg; continue; case EOF: break; @@ -155,13 +153,11 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { keyid, 'k', "keyid", "calculate key identifiers of a key/certificate", - {"[--in file] [--type rsa-priv|ecdsa-priv|pub|pkcs10|x509]", - "[--debug 0|1|2|3|4]"}, + {"[--in file] [--type rsa-priv|ecdsa-priv|pub|pkcs10|x509]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, {"type", 't', 1, "type of key, default: rsa-priv"}, - {"debug", 'v', 1, "set debug level, default: 1"}, } }); } diff --git a/src/pki/commands/pub.c b/src/pki/commands/pub.c index 7294179de..de0444c1a 100644 --- a/src/pki/commands/pub.c +++ b/src/pki/commands/pub.c @@ -21,7 +21,7 @@ /** * Extract a public key from a private key/certificate */ -static int pub(int argc, char *argv[]) +static int pub() { key_encoding_type_t form = KEY_PUB_SPKI_ASN1_DER; credential_type_t type = CRED_PRIVATE_KEY; @@ -32,33 +32,31 @@ static int pub(int argc, char *argv[]) chunk_t encoding; char *file = NULL; void *cred; + char *arg; while (TRUE) { - switch (getopt_long(argc, argv, command_optstring, command_opts, NULL)) + switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); - case 'v': - dbg_level = atoi(optarg); - continue; case 't': - if (streq(optarg, "rsa")) + if (streq(arg, "rsa")) { type = CRED_PRIVATE_KEY; subtype = KEY_RSA; } - else if (streq(optarg, "ecdsa")) + else if (streq(arg, "ecdsa")) { type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } - else if (streq(optarg, "pkcs10")) + else if (streq(arg, "pkcs10")) { type = CRED_CERTIFICATE; subtype = CERT_PKCS10_REQUEST; } - else if (streq(optarg, "x509")) + else if (streq(arg, "x509")) { type = CRED_CERTIFICATE; subtype = CERT_X509; @@ -69,13 +67,13 @@ static int pub(int argc, char *argv[]) } continue; case 'f': - if (!get_form(optarg, &form, TRUE)) + if (!get_form(arg, &form, TRUE)) { return command_usage("invalid output format"); } continue; case 'i': - file = optarg; + file = arg; continue; case EOF: break; @@ -147,14 +145,12 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { pub, 'p', "pub", "extract the public key from a private key/certificate", - {"[--in file] [--type rsa|ecdsa|pkcs10|x509] [--outform der|pem|pgp]", - "[--debug 0|1|2|3|4]"}, + {"[--in file] [--type rsa|ecdsa|pkcs10|x509] [--outform der|pem|pgp]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, {"type", 't', 1, "type of credential, default: rsa"}, {"outform", 'f', 1, "encoding of extracted public key"}, - {"debug", 'v', 1, "set debug level, default: 1"}, } }); } diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c index 97eb78382..5d11acc2a 100644 --- a/src/pki/commands/self.c +++ b/src/pki/commands/self.c @@ -18,14 +18,13 @@ #include "pki.h" #include <utils/linked_list.h> -#include <utils/optionsfrom.h> #include <credentials/certificates/certificate.h> #include <credentials/certificates/x509.h> /** * Create a self signed certificate. */ -static int self(int argc, char *argv[]) +static int self() { key_type_t type = KEY_RSA; hash_algorithm_t digest = HASH_SHA1; @@ -40,34 +39,26 @@ static int self(int argc, char *argv[]) chunk_t encoding = chunk_empty; time_t not_before, not_after; x509_flag_t flags = 0; - options_t *options; + char *arg; - options = options_create(); san = linked_list_create(); ocsp = linked_list_create(); while (TRUE) { - switch (getopt_long(argc, argv, command_optstring, command_opts, NULL)) + switch (command_getopt(&arg)) { case 'h': goto usage; case 'v': - dbg_level = atoi(optarg); - continue; - case '+': - if (!options->from(options, optarg, &argc, &argv, optind)) - { - error = "invalid options file"; - goto usage; - } + dbg_level = atoi(arg); continue; case 't': - if (streq(optarg, "rsa")) + if (streq(arg, "rsa")) { type = KEY_RSA; } - else if (streq(optarg, "ecdsa")) + else if (streq(arg, "ecdsa")) { type = KEY_ECDSA; } @@ -78,7 +69,7 @@ static int self(int argc, char *argv[]) } continue; case 'g': - digest = get_digest(optarg); + digest = get_digest(arg); if (digest == HASH_UNKNOWN) { error = "invalid --digest type"; @@ -86,16 +77,16 @@ static int self(int argc, char *argv[]) } continue; case 'i': - file = optarg; + file = arg; continue; case 'd': - dn = optarg; + dn = arg; continue; case 'a': - san->insert_last(san, identification_create_from_string(optarg)); + san->insert_last(san, identification_create_from_string(arg)); continue; case 'l': - lifetime = atoi(optarg); + lifetime = atoi(arg); if (!lifetime) { error = "invalid --lifetime value"; @@ -103,13 +94,13 @@ static int self(int argc, char *argv[]) } continue; case 's': - hex = optarg; + hex = arg; continue; case 'b': flags |= X509_CA; continue; case 'o': - ocsp->insert_last(ocsp, optarg); + ocsp->insert_last(ocsp, arg); continue; case EOF: break; @@ -201,7 +192,6 @@ end: DESTROY_IF(private); san->destroy_offset(san, offsetof(identification_t, destroy)); ocsp->destroy(ocsp); - options->destroy(options); free(encoding.ptr); free(serial.ptr); @@ -215,7 +205,6 @@ end: usage: san->destroy_offset(san, offsetof(identification_t, destroy)); ocsp->destroy(ocsp); - options->destroy(options); return command_usage(error); } @@ -230,8 +219,7 @@ static void __attribute__ ((constructor))reg() {"[--in file] [--type rsa|ecdsa]", " --dn distinguished-name [--san subjectAltName]+", "[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+", - "[--digest md5|sha1|sha224|sha256|sha384|sha512]", - "[--options file]"}, + "[--digest md5|sha1|sha224|sha256|sha384|sha512]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "private key input file, default: stdin"}, @@ -243,8 +231,6 @@ static void __attribute__ ((constructor))reg() {"ca", 'b', 0, "include CA basicConstraint, default: no"}, {"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"}, {"digest", 'g', 1, "digest for signature creation, default: sha1"}, - {"debug", 'v', 1, "set debug level, default: 1"}, - {"options", '+', 1, "read command line options from file"}, } }); } diff --git a/src/pki/commands/verify.c b/src/pki/commands/verify.c index 26a6dca5d..c0595e044 100644 --- a/src/pki/commands/verify.c +++ b/src/pki/commands/verify.c @@ -21,26 +21,24 @@ /** * Verify a certificate signature */ -static int verify(int argc, char *argv[]) +static int verify() { certificate_t *cert, *ca; char *file = NULL, *cafile = NULL; bool good = FALSE; + char *arg; while (TRUE) { - switch (getopt_long(argc, argv, command_optstring, command_opts, NULL)) + switch (command_getopt(&arg)) { case 'h': return command_usage(NULL); - case 'v': - dbg_level = atoi(optarg); - continue; case 'i': - file = optarg; + file = arg; continue; case 'c': - cafile = optarg; + cafile = arg; continue; case EOF: break; @@ -132,7 +130,6 @@ static void __attribute__ ((constructor))reg() {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "x509 certifcate to verify, default: stdin"}, {"cacert", 'c', 1, "CA certificate, default: verify self signed"}, - {"debug", 'v', 1, "set debug level, default: 1"}, } }); } |