mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Add generation of shell autocompletion scripts to chzcrypt, lszcrypt and zcryptstats. Acked-by: Steffen Eiden <seiden@linux.ibm.com> Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com> Signed-off-by: Szabina Korbai <szkorbai@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
696 lines
20 KiB
C
696 lines
20 KiB
C
/*
|
|
* chzcrypt - Tool to modify zcrypt configuration
|
|
*
|
|
* Copyright IBM Corp. 2008, 2023
|
|
*
|
|
* s390-tools is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
#include <argz.h>
|
|
#include <err.h>
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#include "lib/util_base.h"
|
|
#include "lib/util_file.h"
|
|
#include "lib/util_libc.h"
|
|
#include "lib/util_opt.h"
|
|
#include "lib/util_panic.h"
|
|
#include "lib/util_path.h"
|
|
#include "lib/util_prg.h"
|
|
#include "lib/util_scandir.h"
|
|
#include "lib/zt_common.h"
|
|
|
|
#include "chzcrypt_cli.h"
|
|
#include "misc.h"
|
|
|
|
/* max seconds the se-association command will wait for completion */
|
|
#define MAX_ASSOC_POLL_TIME_IN_S 30
|
|
|
|
/* max seconds the se-unbind command will wait for unbind complete */
|
|
#define MAX_UNBIND_POLL_TIME_IN_S 30
|
|
|
|
/*
|
|
* Private data
|
|
*/
|
|
static struct chzcrypt_l {
|
|
int verbose;
|
|
} l;
|
|
|
|
/*
|
|
* Program configuration
|
|
*/
|
|
static const struct util_prg prg = {
|
|
.desc = "Modify zcrypt configuration.",
|
|
.args = "[DEVICE_IDS]",
|
|
.copyright_vec = {
|
|
{
|
|
.owner = "IBM Corp.",
|
|
.pub_first = 2008,
|
|
.pub_last = 2023,
|
|
},
|
|
UTIL_PRG_COPYRIGHT_END
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Print if verbose is set
|
|
*/
|
|
#define verbose(x...) \
|
|
do { \
|
|
if (!l.verbose) \
|
|
break; \
|
|
printf(x); \
|
|
} while (0)
|
|
|
|
/*
|
|
* Set poll settings
|
|
*/
|
|
static void poll_thread_set(const char *mode_str)
|
|
{
|
|
long mode, mode_read = -1;
|
|
char *attr;
|
|
|
|
sscanf(mode_str, "%ld", &mode);
|
|
if (mode == 1)
|
|
verbose("Enabling poll thread.\n");
|
|
else
|
|
verbose("Disabling poll thread.\n");
|
|
attr = util_path_sysfs("bus/ap/poll_thread");
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - can't write to %s.\n Wrong permissions"
|
|
" or wrong tools version.", attr);
|
|
util_file_write_l(mode, 10, attr);
|
|
util_file_read_l(&mode_read, 10, attr);
|
|
if (mode != mode_read)
|
|
errx(EXIT_FAILURE, "Error - unable to change poll thread setting.");
|
|
free(attr);
|
|
}
|
|
|
|
/*
|
|
* Set timer
|
|
*/
|
|
static void config_time_set(const char *timeout_str)
|
|
{
|
|
long timeout, timeout_read;
|
|
char *attr;
|
|
|
|
if (sscanf(timeout_str, "%ld", &timeout) != 1) {
|
|
errx(EXIT_FAILURE, "Error - invalid configuration timeout '%s'.", timeout_str);
|
|
}
|
|
attr = util_path_sysfs("bus/ap/config_time");
|
|
verbose("Setting configuration timer to %ld seconds.\n", timeout);
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - can't write to %s.\n Wrong permissions"
|
|
" or wrong tools version.", attr);
|
|
util_file_write_l(timeout, 10, attr);
|
|
util_file_read_l(&timeout_read, 10, attr);
|
|
if (timeout != timeout_read)
|
|
errx(EXIT_FAILURE, "Error - unable to change configuration timer setting.");
|
|
free(attr);
|
|
}
|
|
|
|
/*
|
|
* Set poll timeout
|
|
*/
|
|
static void poll_timeout_set(const char *poll_timeout_str)
|
|
{
|
|
long poll_timeout, poll_timeout_read;
|
|
char *attr;
|
|
|
|
if (sscanf(poll_timeout_str, "%ld", &poll_timeout) != 1)
|
|
errx(EXIT_FAILURE, "Error - invalid poll timeout '%s'.", poll_timeout_str);
|
|
attr = util_path_sysfs("bus/ap/poll_timeout");
|
|
verbose("Setting poll timeout to %ld seconds.\n", poll_timeout);
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - can't write to %s.\n Wrong permissions"
|
|
" or wrong tools version.", attr);
|
|
util_file_write_l(poll_timeout, 10, attr);
|
|
util_file_read_l(&poll_timeout_read, 10, attr);
|
|
if (poll_timeout != poll_timeout_read)
|
|
errx(EXIT_FAILURE, "Error - unable to change poll timeout setting.");
|
|
free(attr);
|
|
}
|
|
|
|
/*
|
|
* Set default domain
|
|
*/
|
|
static void default_domain_set(const char *default_domain_str)
|
|
{
|
|
long max_dom, default_domain, default_domain_read;
|
|
char *attr, *ap_max_domain_id, *ap;
|
|
char use_dom_mask[80];
|
|
|
|
/* check if ap driver is available */
|
|
ap = util_path_sysfs("bus/ap");
|
|
if (!util_path_is_dir(ap))
|
|
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
|
|
|
/* read usage domain mask */
|
|
util_file_read_line(use_dom_mask, sizeof(use_dom_mask),
|
|
"%s/ap_usage_domain_mask", ap);
|
|
|
|
sscanf(default_domain_str, "%li", &default_domain);
|
|
ap_max_domain_id = util_path_sysfs("bus/ap/ap_max_domain_id");
|
|
util_file_read_l(&max_dom, 10, ap_max_domain_id);
|
|
if (default_domain < 0 || default_domain > max_dom)
|
|
errx(EXIT_FAILURE, "Error - invalid default domain '%s'.", default_domain_str);
|
|
attr = util_path_sysfs("bus/ap/ap_domain");
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - can't write to %s.\n Wrong permissions"
|
|
" or wrong tools version.", attr);
|
|
verbose("Setting default domain to %ld.\n", default_domain);
|
|
util_file_write_l(default_domain, 10, attr);
|
|
util_file_read_l(&default_domain_read, 10, attr);
|
|
if (default_domain != default_domain_read)
|
|
errx(EXIT_FAILURE, "Error - unable to change default domain.");
|
|
|
|
/* give a warning, when the fresh set default domain is unavailable */
|
|
if (default_domain < 0 || check_mask_bit(use_dom_mask, default_domain) < 1)
|
|
printf("Warning: Default domain 0x%02lx is not available.\n", default_domain);
|
|
|
|
free(ap_max_domain_id);
|
|
free(attr);
|
|
free(ap);
|
|
}
|
|
|
|
static void set_online(const char *online, const char *online_text,
|
|
char *dev_list, size_t len)
|
|
{
|
|
long value;
|
|
int id, dom;
|
|
char *dev, *dev_path;
|
|
char device[256], online_read[32];
|
|
|
|
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
|
if (strncmp(dev, "card", 4) == 0) {
|
|
/* dev == "card2" */
|
|
if (sscanf(dev, "card%02x", &id) != 1)
|
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
|
sprintf(device, "card%02x", id);
|
|
} else if (strncmp(dev, "0x", 2) == 0) {
|
|
/* dev == "0x.." */
|
|
if (sscanf(dev, "0x%02x", &id) != 1)
|
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
|
sprintf(device, "card%02x", id);
|
|
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
|
/* dev == "2" */
|
|
if (sscanf(dev, "%02x", &id) != 1)
|
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
|
sprintf(device, "card%02x", id);
|
|
} else {
|
|
/* Form: 01.0003 ? */
|
|
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
|
|
errx(EXIT_FAILURE,
|
|
"Error - cryptographic device %s malformed.", dev);
|
|
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
|
|
}
|
|
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
|
if (!util_path_is_dir(dev_path))
|
|
errx(EXIT_FAILURE,
|
|
"Error - cryptographic device %s does not exist.", device);
|
|
if (!util_path_is_writable("%s/online", dev_path))
|
|
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n"
|
|
" Wrong permissions or wrong tools version.", dev_path);
|
|
if (*online == '1' && util_path_is_readable("%s/config", dev_path)) {
|
|
util_file_read_l(&value, 10, "%s/config", dev_path);
|
|
if (value <= 0) {
|
|
warnx("Warning - device %s is deconfigured,"
|
|
" can't set to online.\n", dev);
|
|
goto next;
|
|
}
|
|
}
|
|
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
|
util_file_write_s(online, "%s/online", dev_path);
|
|
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
|
if (strcmp(online, online_read) != 0)
|
|
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
|
device, online_text);
|
|
next:
|
|
free(dev_path);
|
|
}
|
|
}
|
|
|
|
static void set_config(const char *config, const char *config_text,
|
|
char *dev_list, size_t len)
|
|
{
|
|
int id;
|
|
char *dev, *dev_path;
|
|
char device[256], config_read[32];
|
|
|
|
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
|
if (strncmp(dev, "card", 4) == 0) {
|
|
/* dev == "card2" */
|
|
if (sscanf(dev, "card%02x", &id) != 1)
|
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
|
sprintf(device, "card%02x", id);
|
|
} else if (strncmp(dev, "0x", 2) == 0) {
|
|
/* dev == "0x.." */
|
|
if (sscanf(dev, "0x%02x", &id) != 1)
|
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
|
sprintf(device, "card%02x", id);
|
|
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
|
/* dev == "2" */
|
|
if (sscanf(dev, "%02x", &id) != 1)
|
|
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
|
sprintf(device, "card%02x", id);
|
|
} else {
|
|
errx(EXIT_FAILURE, "Error - invalid device %s\n"
|
|
" Config on/off is only valid for card devices.", dev);
|
|
}
|
|
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
|
if (!util_path_is_dir(dev_path))
|
|
errx(EXIT_FAILURE,
|
|
"Error - cryptographic device %s does not exist.", device);
|
|
if (!util_path_is_readable("%s/config", dev_path))
|
|
errx(EXIT_FAILURE, "Error - can't read %s/config.\n"
|
|
"File may not exist due to an older zcrypt device driver.", dev_path);
|
|
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
|
|
if (strcmp(config, config_read) == 0) {
|
|
warnx("Warning - device %s is already %s.", device, config_text);
|
|
goto next;
|
|
}
|
|
if (!util_path_is_writable("%s/config", dev_path))
|
|
errx(EXIT_FAILURE, "Error - can't write to %s/config.\n"
|
|
"Wrong permissions or wrong tools version.", dev_path);
|
|
verbose("Setting cryptographic device %s %s\n", device, config_text);
|
|
util_file_write_s(config, "%s/config", dev_path);
|
|
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
|
|
if (strcmp(config, config_read) != 0)
|
|
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
|
device, config_text);
|
|
next:
|
|
free(dev_path);
|
|
}
|
|
}
|
|
|
|
static void se_assoc(const char *assoc_idx, const char *dev)
|
|
{
|
|
int i, idx, rc, ap, dom, loop;
|
|
char *dev_path, *attr;
|
|
char buf[256];
|
|
|
|
if (!ap_bus_has_SB_support())
|
|
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
|
|
|
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
|
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
|
dev);
|
|
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
|
ap, ap, dom);
|
|
if (!util_path_is_dir(dev_path))
|
|
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
|
dev);
|
|
|
|
if (sscanf(assoc_idx, "%i", &idx) != 1)
|
|
errx(EXIT_FAILURE, "Error - Can't parse association index '%s' as number.",
|
|
assoc_idx);
|
|
if (idx < 0 || idx > 0xFFFF)
|
|
errx(EXIT_FAILURE, "Error - Association index needs to be in range [0...%d].",
|
|
0xffff);
|
|
|
|
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_associate",
|
|
ap, ap, dom);
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
|
|
/* read se_associate attribute and check for 'unassociated' */
|
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
if (strcmp(buf, "unassociated"))
|
|
errx(EXIT_FAILURE,
|
|
"Error - Queue device %s is NOT in 'unassociated' state (state '%s' found).",
|
|
dev, buf);
|
|
|
|
/* write assocition index to the se_associate attribute */
|
|
rc = util_file_write_l(idx, 10, attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
|
|
/* loop up to MAX_ASSOC_POLL_TIME_IN_S seconds for completion */
|
|
for (loop = 0; loop < 2 * MAX_ASSOC_POLL_TIME_IN_S; usleep(500000), loop++) {
|
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
if (!strncmp(buf, "associated", strlen("associated")))
|
|
break;
|
|
if (!strcmp(buf, "unassociated"))
|
|
errx(EXIT_FAILURE,
|
|
"Error - Failure associating queue device %s (state '%s' found).",
|
|
dev, buf);
|
|
}
|
|
if (loop >= 2 * MAX_ASSOC_POLL_TIME_IN_S)
|
|
errx(EXIT_FAILURE,
|
|
"Error - Failure associating queue device %s (timeout after %d s).",
|
|
dev, MAX_ASSOC_POLL_TIME_IN_S);
|
|
|
|
if (sscanf(buf, "associated %d", &i) != 1 || idx != i)
|
|
errx(EXIT_FAILURE,
|
|
"Error - Failure associating queue device %s (state '%s' found).",
|
|
dev, buf);
|
|
|
|
verbose("Queue device %s successful associated with index %d.\n",
|
|
dev, idx);
|
|
|
|
free(dev_path);
|
|
free(attr);
|
|
}
|
|
|
|
static void se_bind(const char *dev)
|
|
{
|
|
char *dev_path, *attr;
|
|
int rc, ap, dom;
|
|
char buf[256];
|
|
|
|
if (!ap_bus_has_SB_support())
|
|
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
|
|
|
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
|
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
|
dev);
|
|
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
|
ap, ap, dom);
|
|
if (!util_path_is_dir(dev_path))
|
|
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
|
dev);
|
|
|
|
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
|
|
ap, ap, dom);
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
|
|
/* read se_bind attribute and check for 'unboud' */
|
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
if (strcmp(buf, "unbound"))
|
|
errx(EXIT_FAILURE,
|
|
"Error - Queue device %s is NOT in 'unbound' state (state '%s' found).",
|
|
dev, buf);
|
|
|
|
/* write se_bind attribute, check for 'bound' afterwards */
|
|
rc = util_file_write_l(1, 10, attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
if (strcmp(buf, "bound"))
|
|
errx(EXIT_FAILURE, "Error - Failure binding queue device %s (state '%s' found).",
|
|
dev, buf);
|
|
|
|
verbose("Queue device %s successful bound.\n", dev);
|
|
|
|
free(dev_path);
|
|
free(attr);
|
|
}
|
|
|
|
static void se_unbind(const char *dev)
|
|
{
|
|
int rc, ap, dom, loop;
|
|
char *dev_path, *attr;
|
|
char buf[256];
|
|
|
|
if (!ap_bus_has_SB_support())
|
|
errx(EXIT_FAILURE, "Error - AP bus: SE bind support is not available.");
|
|
|
|
if (sscanf(dev, "%02x.%04x", &ap, &dom) != 2)
|
|
errx(EXIT_FAILURE, "Error - Can't parse queue device '%s' as xy.abcd.",
|
|
dev);
|
|
dev_path = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x",
|
|
ap, ap, dom);
|
|
if (!util_path_is_dir(dev_path))
|
|
errx(EXIT_FAILURE, "Error - Queue device %s does not exist.",
|
|
dev);
|
|
|
|
attr = util_path_sysfs("bus/ap/devices/card%02x/%02x.%04x/se_bind",
|
|
ap, ap, dom);
|
|
if (!util_path_is_writable(attr))
|
|
errx(EXIT_FAILURE, "Error - Can't write to %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
|
|
/* write se_bind attribute */
|
|
rc = util_file_write_l(0, 10, attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure writing to %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
|
|
/* loop up to MAX_UNBIND_POLL_TIME_IN_S seconds for completion */
|
|
for (loop = 0; loop < 2 * MAX_UNBIND_POLL_TIME_IN_S; usleep(500000), loop++) {
|
|
rc = util_file_read_line(buf, sizeof(buf), attr);
|
|
if (rc)
|
|
errx(EXIT_FAILURE, "Error - Failure reading from %s (errno '%s').",
|
|
attr, strerror(errno));
|
|
if (!strcmp(buf, "unbound"))
|
|
break;
|
|
}
|
|
if (loop >= 2 * MAX_UNBIND_POLL_TIME_IN_S)
|
|
errx(EXIT_FAILURE,
|
|
"Error - Failure unbinding queue device %s (timeout after %d s).",
|
|
dev, MAX_UNBIND_POLL_TIME_IN_S);
|
|
|
|
verbose("Queue device %s successful unbound.\n", dev);
|
|
|
|
free(dev_path);
|
|
free(attr);
|
|
}
|
|
|
|
/*
|
|
* Print invalid commandline error message and then exit with error code
|
|
*/
|
|
#define invalid_cmdline_exit(x...) \
|
|
do { \
|
|
fprintf(stderr, "%s: ", program_invocation_short_name); \
|
|
fprintf(stderr, x); \
|
|
util_prg_print_parse_error(); \
|
|
exit(EXIT_FAILURE); \
|
|
} while (0)
|
|
|
|
/*
|
|
* Get device list from sysfs
|
|
*/
|
|
static void dev_list_all(char **argz, size_t *len)
|
|
{
|
|
struct dirent **de_vec;
|
|
int count, i;
|
|
char *path;
|
|
|
|
path = util_path_sysfs("bus/ap/devices/");
|
|
count = util_scandir(&de_vec, NULL, path, "card.*");
|
|
if (count < 0)
|
|
errx(EXIT_FAILURE, "Error - Could not read directory %s.", path);
|
|
*argz = NULL;
|
|
*len = 0;
|
|
for (i = 0; i < count; i++)
|
|
util_assert(argz_add(argz, len, de_vec[i]->d_name) == 0,
|
|
"Out of memory\n");
|
|
util_scandir_free(de_vec, count);
|
|
free(path);
|
|
}
|
|
|
|
/*
|
|
* Get device list from commandline
|
|
*/
|
|
static void dev_list_argv(char **argz, size_t *len, char * const argv[])
|
|
{
|
|
if (argv[0] == NULL)
|
|
errx(EXIT_FAILURE, "Need to specify at least one device ID.");
|
|
|
|
util_assert(argz_create(argv, argz, len) == 0, "Out of memory\n");
|
|
}
|
|
|
|
/*
|
|
* Describe adapter ids
|
|
*/
|
|
static void print_adapter_id_help(void)
|
|
{
|
|
printf("\n");
|
|
printf("DEVICE_IDS\n");
|
|
printf(" List of cryptographic device ids separated by blanks which will be set\n");
|
|
printf(" online/offline. Must be used in conjunction with the enable or disable option.\n");
|
|
printf(" DEVICE_ID could either be card device id ('<card-id>') or queue device id\n");
|
|
printf(" '<card-id>.<domain-id>').\n\n");
|
|
printf("QUEUE_DEVICE:\n");
|
|
printf(" An APQN queue device given as xy.abcd as it is listed by lszcrypt -V.\n\n");
|
|
printf("EXAMPLE:\n");
|
|
printf(" Disable the cryptographic device with card id '02' (inclusive all queues).\n");
|
|
printf(" #>chzcrypt -d 02\n");
|
|
printf(" \n");
|
|
printf(" Enable the cryptographic devices with card id '03' and domain id '0005'.\n");
|
|
printf(" #>chzcrypt -e 03.0005\n");
|
|
printf(" \n");
|
|
}
|
|
|
|
/*
|
|
* Parse options and execute the command
|
|
*/
|
|
int main(int argc, char *argv[])
|
|
{
|
|
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
|
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
|
|
const char *config_time = NULL, *poll_timeout = NULL;
|
|
const char *queue_device = NULL, *assoc_idx = NULL;
|
|
int c, i, j, action = 0;
|
|
char *path, *dev_list;
|
|
bool all = false;
|
|
size_t len;
|
|
|
|
for (i=0; i < argc; i++)
|
|
for (j=2; j < (int) strlen(argv[i]); j++)
|
|
if (argv[i][j] == '_')
|
|
argv[i][j] = '-';
|
|
|
|
util_prg_init(&prg);
|
|
util_opt_init(chzcrypt_opt_vec, NULL);
|
|
while (1) {
|
|
c = util_opt_getopt_long(argc, argv);
|
|
if (c == -1)
|
|
break;
|
|
switch (c) {
|
|
case 'e':
|
|
action = c;
|
|
online = "1";
|
|
online_text = "online";
|
|
break;
|
|
case 'd':
|
|
action = c;
|
|
online = "0";
|
|
online_text = "offline";
|
|
break;
|
|
case 'a':
|
|
all = true;
|
|
break;
|
|
case 'p':
|
|
action = c;
|
|
poll_thread = "1";
|
|
break;
|
|
case 'n':
|
|
action = c;
|
|
poll_thread = "0";
|
|
break;
|
|
case 'c':
|
|
action = c;
|
|
config_time = optarg;
|
|
break;
|
|
case 't':
|
|
action = c;
|
|
poll_timeout = optarg;
|
|
break;
|
|
case 'q':
|
|
action = c;
|
|
default_domain = optarg;
|
|
break;
|
|
case 'V':
|
|
l.verbose = true;
|
|
break;
|
|
case 'h':
|
|
util_prg_print_help();
|
|
util_opt_print_help();
|
|
print_adapter_id_help();
|
|
return EXIT_SUCCESS;
|
|
case 'v':
|
|
util_prg_print_version();
|
|
return EXIT_SUCCESS;
|
|
case OPT_CONFIG_ON:
|
|
action = c;
|
|
config = "1";
|
|
config_text = "config on";
|
|
break;
|
|
case OPT_CONFIG_OFF:
|
|
action = c;
|
|
config = "0";
|
|
config_text = "config off";
|
|
break;
|
|
case OPT_SE_ASSOC:
|
|
action = c;
|
|
assoc_idx = optarg;
|
|
break;
|
|
case OPT_SE_BIND:
|
|
action = c;
|
|
break;
|
|
case OPT_SE_UNBIND:
|
|
action = c;
|
|
break;
|
|
default:
|
|
util_opt_print_parse_error(c, argv);
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
if (!action)
|
|
invalid_cmdline_exit("Error - missing argument.\n");
|
|
path = util_path_sysfs("bus/ap");
|
|
if (!util_path_is_dir(path))
|
|
errx(EXIT_FAILURE, "Crypto device driver not available.");
|
|
free(path);
|
|
if (poll_thread) {
|
|
poll_thread_set(poll_thread);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
if (config_time) {
|
|
config_time_set(config_time);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
if (poll_timeout) {
|
|
poll_timeout_set(poll_timeout);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
if (default_domain) {
|
|
default_domain_set(default_domain);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
if (action == OPT_SE_ASSOC) {
|
|
if (optind >= argc)
|
|
errx(EXIT_FAILURE,
|
|
"Error - The --se-associate needs a queue device given.");
|
|
queue_device = argv[optind];
|
|
se_assoc(assoc_idx, queue_device);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
if (action == OPT_SE_BIND) {
|
|
if (optind >= argc)
|
|
errx(EXIT_FAILURE,
|
|
"Error - The --se-bind needs a queue device given.");
|
|
queue_device = argv[optind];
|
|
se_bind(queue_device);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
if (action == OPT_SE_UNBIND) {
|
|
if (optind >= argc)
|
|
errx(EXIT_FAILURE,
|
|
"Error - The --se-unbind needs a queue device given.");
|
|
queue_device = argv[optind];
|
|
se_unbind(queue_device);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
if (all)
|
|
dev_list_all(&dev_list, &len);
|
|
else
|
|
dev_list_argv(&dev_list, &len, &argv[optind]);
|
|
|
|
if ((online || config) && len == 0)
|
|
errx(EXIT_FAILURE, "Error - missing cryptographic device id(s).");
|
|
|
|
if (online)
|
|
set_online(online, online_text, dev_list, len);
|
|
else if (config)
|
|
set_config(config, config_text, dev_list, len);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|