/*
* Copyright (C) 2015, Trustees of Indiana University
*
+ * Copyright (c) 2016, Intel Corporation.
+ *
* Author: Jeremy Filizetti <jfilizet@iu.edu>
*/
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <lnet/nidstr.h>
-#include <lustre/lustre_idl.h>
+#include <linux/lustre/lustre_user.h>
#include "sk_utils.h"
#include "err_util.h"
#define SK_DEFAULT_PRIME_BITS 2048
#define SK_DEFAULT_NODEMAP "default"
-/* Names match up with openssl enc and dgst commands */
-char *sk_crypt2name[] = {
- [SK_CRYPT_EMPTY] = "NONE",
- [SK_CRYPT_AES256_CTR] = "AES-256-CTR",
-};
-
-char *sk_hmac2name[] = {
- [SK_HMAC_EMPTY] = "NONE",
- [SK_HMAC_SHA256] = "SHA256",
- [SK_HMAC_SHA512] = "SHA512",
-};
-
-int sk_name2crypt(char *name)
-{
- int i;
-
- for (i = 0; i < SK_CRYPT_MAX; i++) {
- if (strcasecmp(name, sk_crypt2name[i]) == 0)
- return i;
- }
-
- return SK_CRYPT_INVALID;
-}
-
-int sk_name2hmac(char *name)
-{
- int i;
-
- for (i = 0; i < SK_HMAC_MAX; i++) {
- if (strcasecmp(name, sk_hmac2name[i]) == 0)
- return i;
- }
-
- return SK_HMAC_INVALID;
-}
-
-void usage(FILE *fp, char *program)
+static void usage(FILE *fp, char *program)
{
int i;
fprintf(fp, "Modify/Write Options:\n");
fprintf(fp, "-c|--crypt <num> Cipher for encryption "
"(Default: AES Counter mode)\n");
- for (i = 1; i < SK_CRYPT_MAX; i++)
- fprintf(fp, " %s\n", sk_crypt2name[i]);
-
+ for (i = 1; i < ARRAY_SIZE(sk_crypt_algs); i++)
+ fprintf(fp, " %s\n",
+ sk_crypt_algs[i].sct_name);
fprintf(fp, "-i|--hmac <num> Hash algorithm for integrity "
"(Default: SHA256)\n");
- for (i = 1; i < SK_HMAC_MAX; i++)
- fprintf(fp, " %s\n", sk_hmac2name[i]);
-
+ for (i = 1; i < ARRAY_SIZE(sk_hmac_algs); i++)
+ fprintf(fp, " %s\n",
+ sk_hmac_algs[i].sht_name);
fprintf(fp, "-e|--expire <num> Seconds before contexts from "
"key expire (Default: %d seconds (%.3g days))\n",
SK_DEFAULT_EXPIRE, (double)SK_DEFAULT_EXPIRE / 3600 / 24);
"client)\n");
fprintf(fp, "-k|--key-bits <len> Shared key length in bits "
"(Default: %d)\n", SK_DEFAULT_SK_KEYLEN);
- fprintf(fp, "-d|--data <file> Key random data source "
- "(Default: /dev/random)\n\n");
+ fprintf(fp, "-d|--data <file> Key data source for new keys "
+ "(Default: /dev/random)\n");
+ fprintf(fp, " Not a seed value. "
+ "This is the actual key value.\n\n");
fprintf(fp, "Other Options:\n");
fprintf(fp, "-v|--verbose Increase verbosity for errors\n");
exit(EXIT_FAILURE);
}
-ssize_t get_key_data(char *src, void *buffer, size_t bits)
+static ssize_t get_key_data(char *src, void *buffer, size_t bits)
{
char *ptr = buffer;
size_t remain;
return rc;
}
-int write_config_file(char *output_file, struct sk_keyfile_config *config,
- bool overwrite)
+static int write_config_file(char *output_file,
+ struct sk_keyfile_config *config, bool overwrite)
{
size_t rc;
int fd;
return rc;
}
-int print_config(char *filename)
+static int print_config(char *filename)
{
struct sk_keyfile_config *config;
int i;
if (config->skc_type & SK_TYPE_CLIENT)
printf(" client");
printf("\n");
- printf("HMAC alg: %s\n", sk_hmac2name[config->skc_hmac_alg]);
- printf("Crypto alg: %s\n", sk_crypt2name[config->skc_crypt_alg]);
+ printf("HMAC alg: %s\n", sk_hmac2name(config->skc_hmac_alg));
+ printf("Crypto alg: %s\n", sk_crypt2name(config->skc_crypt_alg));
printf("Ctx Expiration: %u seconds\n", config->skc_expire);
printf("Shared keylen: %u bits\n", config->skc_shared_keylen);
printf("Prime length: %u bits\n", config->skc_prime_bits);
return EXIT_SUCCESS;
}
-int parse_mgsnids(char *mgsnids, struct sk_keyfile_config *config)
+static int parse_mgsnids(char *mgsnids, struct sk_keyfile_config *config)
{
lnet_nid_t nid;
char *ptr;
int main(int argc, char **argv)
{
struct sk_keyfile_config *config;
- char *data = NULL;
+ char *datafile = NULL;
char *input = NULL;
char *load = NULL;
char *modify = NULL;
int verbose = 0;
int i;
int opt;
- enum sk_key_type type = SK_TYPE_INVALID;
+ enum sk_key_type type = SK_TYPE_INVALID;
bool generate_prime = false;
DH *dh;
- static struct option long_opt[] = {
- {"crypt", 1, 0, 'c'},
- {"data", 1, 0, 'd'},
- {"expire", 1, 0, 'e'},
- {"fsname", 1, 0, 'f'},
- {"mgsnids", 1, 0, 'g'},
- {"help", 0, 0, 'h'},
- {"hmac", 1, 0, 'i'},
- {"integrity", 1, 0, 'i'},
- {"key-bits", 1, 0, 'k'},
- {"shared", 1, 0, 'k'},
- {"load", 1, 0, 'l'},
- {"modify", 1, 0, 'm'},
- {"nodemap", 1, 0, 'n'},
- {"prime-bits", 1, 0, 'p'},
- {"read", 1, 0, 'r'},
- {"type", 1, 0, 't'},
- {"verbose", 0, 0, 'v'},
- {"write", 1, 0, 'w'},
- {0, 0, 0, 0},
- };
+ static struct option long_opts[] = {
+ { .name = "crypt", .has_arg = required_argument, .val = 'c'},
+ { .name = "data", .has_arg = required_argument, .val = 'd'},
+ { .name = "expire", .has_arg = required_argument, .val = 'e'},
+ { .name = "fsname", .has_arg = required_argument, .val = 'f'},
+ { .name = "mgsnids", .has_arg = required_argument, .val = 'g'},
+ { .name = "help", .has_arg = no_argument, .val = 'h'},
+ { .name = "hmac", .has_arg = required_argument, .val = 'i'},
+ { .name = "integrity", .has_arg = required_argument, .val = 'i'},
+ { .name = "key-bits", .has_arg = required_argument, .val = 'k'},
+ { .name = "shared", .has_arg = required_argument, .val = 'k'},
+ { .name = "load", .has_arg = required_argument, .val = 'l'},
+ { .name = "modify", .has_arg = required_argument, .val = 'm'},
+ { .name = "nodemap", .has_arg = required_argument, .val = 'n'},
+ { .name = "prime-bits", .has_arg = required_argument, .val = 'p'},
+ { .name = "read", .has_arg = required_argument, .val = 'r'},
+ { .name = "type", .has_arg = required_argument, .val = 't'},
+ { .name = "verbose", .has_arg = no_argument, .val = 'v'},
+ { .name = "write", .has_arg = required_argument, .val = 'w'},
+ { .name = NULL, } };
while ((opt = getopt_long(argc, argv,
- "c:d:e:f:g:hi:l:m:n:p:r:s:k:t:w:v", long_opt,
+ "c:d:e:f:g:hi:l:m:n:p:r:s:k:t:w:v", long_opts,
NULL)) != EOF) {
switch (opt) {
case 'c':
crypt = sk_name2crypt(optarg);
break;
case 'd':
- data = optarg;
+ datafile = optarg;
break;
case 'e':
expire = atoi(optarg);
return EXIT_FAILURE;
}
+ if (modify && datafile) {
+ fprintf(stderr,
+ "error: data file option not valid in key modify\n");
+ return EXIT_FAILURE;
+ }
+
if (modify) {
config = sk_read_file(modify);
if (!config)
return EXIT_FAILURE;
- if (crypt != SK_CRYPT_EMPTY)
- config->skc_crypt_alg = crypt;
- if (hmac != SK_HMAC_EMPTY)
- config->skc_hmac_alg = hmac;
- if (expire != -1)
- config->skc_expire = expire;
- if (shared_keylen != -1)
- config->skc_shared_keylen = shared_keylen;
if (type != SK_TYPE_INVALID) {
/* generate key when adding client type */
if (!(config->skc_type & SK_TYPE_CLIENT) &&
if (config->skc_prime_bits != prime_bits &&
config->skc_type & SK_TYPE_CLIENT)
generate_prime = true;
- config->skc_prime_bits = prime_bits;
}
- if (fsname)
- strncpy(config->skc_fsname, fsname, strlen(fsname));
- if (nodemap)
- strncpy(config->skc_nodemap, nodemap, strlen(nodemap));
- if (mgsnids && parse_mgsnids(mgsnids, config))
- goto error;
- if (sk_validate_config(config)) {
+ } else {
+ /* write mode for a new key */
+ if (!fsname && !mgsnids) {
fprintf(stderr,
- "error: key configuration failed validation\n");
- goto error;
- }
-
- if (data && get_key_data(data, config->skc_shared_key,
- config->skc_shared_keylen)) {
- fprintf(stderr, "error: failure getting key data\n");
- goto error;
+ "error: missing --fsname or --mgsnids\n");
+ return EXIT_FAILURE;
}
- if (generate_prime) {
- printf("Generating DH parameters, "
- "this can take a while...\n");
- dh = DH_generate_parameters(config->skc_prime_bits,
- SK_GENERATOR, NULL, NULL);
- if (BN_num_bytes(dh->p) > SK_MAX_P_BYTES) {
- fprintf(stderr,
- "error: cannot generate DH parameters: "
- "requested length %d over maximum %d\n",
- config->skc_prime_bits,
- SK_MAX_P_BYTES * 8);
- goto error;
- }
- if (BN_bn2bin(dh->p, config->skc_p) !=
- BN_num_bytes(dh->p)) {
- fprintf(stderr,
- "error: convert BIGNUM p to binary "
- "failed\n");
- goto error;
- }
- }
+ config = calloc(1, sizeof(*config));
+ if (!config)
+ return EXIT_FAILURE;
- if (write_config_file(modify, config, true))
+ /* Set the defaults for new key */
+ config->skc_version = SK_CONF_VERSION;
+ config->skc_expire = SK_DEFAULT_EXPIRE;
+ config->skc_shared_keylen = SK_DEFAULT_SK_KEYLEN;
+ config->skc_prime_bits = SK_DEFAULT_PRIME_BITS;
+ config->skc_crypt_alg = SK_CRYPT_AES256_CTR;
+ config->skc_hmac_alg = SK_HMAC_SHA256;
+ for (i = 0; i < MAX_MGSNIDS; i++)
+ config->skc_mgsnids[i] = LNET_NID_ANY;
+
+ if (type == SK_TYPE_INVALID) {
+ fprintf(stderr, "error: no type specified for key\n");
goto error;
+ }
+ config->skc_type = type;
+ generate_prime = type & SK_TYPE_CLIENT;
- return EXIT_SUCCESS;
- }
+ /* SK_DEFAULT_NODEMAP is made to fit in skc_nodemap */
+ strcpy(config->skc_nodemap, SK_DEFAULT_NODEMAP);
- /* write mode for a new key */
- if (!fsname && !mgsnids) {
- fprintf(stderr,
- "error: must provide --fsname, --mgsnids, or both\n");
- return EXIT_FAILURE;
+ if (!datafile)
+ datafile = "/dev/random";
}
- config = malloc(sizeof(*config));
- if (!config)
- return EXIT_FAILURE;
-
- /* Set the defaults */
- memset(config, 0, sizeof(*config));
- config->skc_version = SK_CONF_VERSION;
- config->skc_expire = SK_DEFAULT_EXPIRE;
- config->skc_shared_keylen = SK_DEFAULT_SK_KEYLEN;
- config->skc_prime_bits = SK_DEFAULT_PRIME_BITS;
- config->skc_crypt_alg = SK_CRYPT_AES256_CTR;
- config->skc_hmac_alg = SK_HMAC_SHA256;
- for (i = 0; i < MAX_MGSNIDS; i++)
- config->skc_mgsnids[i] = LNET_NID_ANY;
-
if (crypt != SK_CRYPT_EMPTY)
config->skc_crypt_alg = crypt;
if (hmac != SK_HMAC_EMPTY)
if (prime_bits != -1)
config->skc_prime_bits = prime_bits;
if (fsname)
- strncpy(config->skc_fsname, fsname, strlen(fsname));
+ /* fsname string length was checked when parsing
+ * command-line options
+ */
+ strcpy(config->skc_fsname, fsname);
if (nodemap)
- strncpy(config->skc_nodemap, nodemap, strlen(nodemap));
- else
- strncpy(config->skc_nodemap, SK_DEFAULT_NODEMAP,
- strlen(SK_DEFAULT_NODEMAP));
-
+ /* nodemap string length was checked when parsing
+ * command-line options
+ */
+ strcpy(config->skc_nodemap, nodemap);
if (mgsnids && parse_mgsnids(mgsnids, config))
goto error;
- if (type == SK_TYPE_INVALID) {
- fprintf(stderr, "error: no type specified for key\n");
- goto error;
- }
- config->skc_type = type;
-
if (sk_validate_config(config)) {
fprintf(stderr, "error: key configuration failed validation\n");
goto error;
}
- if (!data)
- data = "/dev/random";
- if (get_key_data(data, config->skc_shared_key,
- config->skc_shared_keylen)) {
- fprintf(stderr, "error: failure getting data for key\n");
+ if (datafile && get_key_data(datafile, config->skc_shared_key,
+ config->skc_shared_keylen)) {
+ fprintf(stderr, "error: failure getting key data from '%s'\n",
+ datafile);
goto error;
}
- if (type & SK_TYPE_CLIENT) {
+ if (generate_prime) {
printf("Generating DH parameters, this can take a while...\n");
dh = DH_generate_parameters(config->skc_prime_bits,
SK_GENERATOR, NULL, NULL);
}
}
- if (write_config_file(output, config, false))
+ if (write_config_file(modify ?: output, config, modify))
goto error;
return EXIT_SUCCESS;
error:
- if (config)
- free(config);
+ free(config);
return EXIT_FAILURE;
}