mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
074de1e14e | ||
|
|
07d181e29b | ||
|
|
895a88b2f8 | ||
|
|
f01f8b240c | ||
|
|
be2bc610b7 | ||
|
|
c48d45ba92 | ||
|
|
886476a207 | ||
|
|
86685f001d | ||
|
|
d619b492e9 | ||
|
|
79e4798061 | ||
|
|
cf2311f1f1 | ||
|
|
7e832da790 | ||
|
|
3b402a0630 | ||
|
|
3437c9bb90 | ||
|
|
8898650266 | ||
|
|
3ae2100d5e | ||
|
|
93e4249fd3 | ||
|
|
8ec4705239 | ||
|
|
cad450fdf9 | ||
|
|
3a1cda59ce | ||
|
|
0566a492ae | ||
|
|
bc7359d2a3 | ||
|
|
db6f272607 | ||
|
|
6db7fbe018 | ||
|
|
2f154fa49d | ||
|
|
148d3f9b64 | ||
|
|
702dc96264 | ||
|
|
313092b202 |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,5 +1,15 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
* __v2.15.x (2020-xx-xx)__
|
||||
|
||||
For Linux kernel version: 5.x
|
||||
|
||||
Changes of existing tools:
|
||||
- hsci: New tool to manage HSCI interfaces
|
||||
- genprotimg: Add host-key document verification support
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
* __v2.15.1 (2020-10-28)__
|
||||
|
||||
For Linux kernel version: 5.9
|
||||
|
||||
2
Makefile
2
Makefile
@@ -9,7 +9,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||
genprotimg lsstp
|
||||
genprotimg lsstp hsci
|
||||
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
|
||||
@@ -249,6 +249,9 @@ Package contents
|
||||
Management Foundation - Web Edition, and is used to manage keys in an
|
||||
enterprise.
|
||||
|
||||
* hsci:
|
||||
Manage HiperSockets Converged Interfaces (HSCI).
|
||||
|
||||
For more information refer to the following publications:
|
||||
|
||||
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
|
||||
@@ -277,7 +280,7 @@ build options:
|
||||
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
||||
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb |
|
||||
| glib2 | `HAVE_GLIB2` | genprotimg |
|
||||
| libcurl | `HAVE_LIBCURL` | libekmfweb |
|
||||
| libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb |
|
||||
|
||||
This table lists additional build or install options:
|
||||
|
||||
|
||||
@@ -2050,7 +2050,7 @@ static int update_dir_levels(int blocks)
|
||||
if (blocks < 2)
|
||||
return 0;
|
||||
|
||||
while (blocks / (PTRS_PER_BLOCK + 1)) {
|
||||
while (blocks / PTRS_PER_BLOCK) {
|
||||
levels++;
|
||||
blocks /= PTRS_PER_BLOCK;
|
||||
}
|
||||
@@ -3103,7 +3103,7 @@ static void update_levels(struct file *f)
|
||||
return;
|
||||
}
|
||||
|
||||
while (blocks / (per_block + 1)) {
|
||||
while (blocks / per_block) {
|
||||
levels++;
|
||||
blocks /= per_block;
|
||||
}
|
||||
|
||||
@@ -366,9 +366,9 @@ install: install_echo install_dirs
|
||||
clean_echo:
|
||||
$(call echocmd," CLEAN ")
|
||||
clean_gcov:
|
||||
rm -f *.gcda *.gcno *.gcov
|
||||
rm -f -- *.gcda *.gcno *.gcov
|
||||
clean_dep:
|
||||
rm -f .*.o.d
|
||||
rm -f -- .*.o.d
|
||||
|
||||
clean: clean_echo clean_gcov clean_dep
|
||||
endif
|
||||
|
||||
@@ -91,13 +91,18 @@ static int read_sfb(unsigned long *min, unsigned long *max)
|
||||
int rc = EXIT_SUCCESS;
|
||||
FILE *fp;
|
||||
|
||||
if (geteuid()) {
|
||||
fprintf(stderr, "Error: Must run as root\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
fp = fopen(PERF_SFB_SIZE, "r");
|
||||
if (fp == NULL) {
|
||||
linux_error(PERF_SFB_SIZE);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
|
||||
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
|
||||
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE
|
||||
"\n");
|
||||
rc = EXIT_FAILURE;
|
||||
} else {
|
||||
if (*min == 0)
|
||||
|
||||
@@ -2572,6 +2572,7 @@ static const char *machine_name(void)
|
||||
case 3906: return "IBM z14";
|
||||
case 3907: return "IBM z14 ZR1";
|
||||
case 8561: return "IBM z15";
|
||||
case 8562: return "IBM z15 Model T02";
|
||||
}
|
||||
return "Unknown hardware model";
|
||||
}
|
||||
@@ -3094,11 +3095,11 @@ int main(int argc, char **argv)
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
ret = read_info();
|
||||
if (ret == EXIT_FAILURE)
|
||||
return ret;
|
||||
ret = parse_args(argc, argv);
|
||||
if (read_info() == EXIT_FAILURE)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
switch ((ret = parse_args(argc, argv))) {
|
||||
switch (ret) {
|
||||
case ACTION_CNT:
|
||||
case ACTION_CNTALL:
|
||||
all = ret == ACTION_CNTALL;
|
||||
@@ -3114,6 +3115,7 @@ int main(int argc, char **argv)
|
||||
case ACTION_NONE:
|
||||
case ACTION_INFO:
|
||||
show_info(&cpumf, ret == ACTION_INFO);
|
||||
ret = EXIT_SUCCESS;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -1637,7 +1637,7 @@ int main(int argc, char *argv[])
|
||||
/* End of options string - start of devices list */
|
||||
break;
|
||||
default:
|
||||
error("Try '%s --help' for more information.");
|
||||
error("Try '%s --help' for more information.", prog_name);
|
||||
}
|
||||
|
||||
if (rc == -1)
|
||||
|
||||
@@ -41,6 +41,10 @@ static const char mode_str[3][10] = {
|
||||
"Full", "Quick", "Expand"
|
||||
};
|
||||
|
||||
/* Report error, free memory, and exit */
|
||||
static void error(const char *format, ...)
|
||||
__attribute__((__noreturn__, __format__(__printf__, 1, 2)));
|
||||
|
||||
#define DASD_PARTN_BITS 2
|
||||
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ clean: clean-recursive
|
||||
$(RECURSIVE_TARGETS):
|
||||
@target=`echo $@ |sed s/-recursive//`; \
|
||||
for d in $(SUBDIRS); do \
|
||||
$(MAKE) -C $$d $$target; \
|
||||
$(MAKE) -C $$d $$target || exit 1; \
|
||||
done
|
||||
|
||||
.PHONY: all install clean $(RECURSIVE_TARGETS)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH GENPROTIMG 8 "March 2020" "s390-tools"
|
||||
.TH GENPROTIMG 8 "November 2020" "s390-tools"
|
||||
.SH NAME
|
||||
genprotimg \- Create a protected virtualization image
|
||||
|
||||
@@ -10,6 +10,7 @@ genprotimg \- Create a protected virtualization image
|
||||
.SY
|
||||
.B genprotimg
|
||||
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
|
||||
\fB\-C\fR \fICERTIFICATE\fR...
|
||||
\fB\-i\fR \fIVMLINUZ\fR
|
||||
[\fB\-r\fR \fIRAMDISK\fR]
|
||||
[\fB\-p\fR \fIPARMFILE\fR]
|
||||
@@ -21,15 +22,19 @@ genprotimg \- Create a protected virtualization image
|
||||
.PP
|
||||
Use \fBgenprotimg\fR to generate a single bootable image file with
|
||||
encrypted and integrity-protected parts. The command requires a kernel
|
||||
image, a host-key document, and an output file name. Optionally,
|
||||
specify an initial RAM filesystem, and a file containing the kernel
|
||||
parameters. Should special circumstances require it, you can
|
||||
image, a host-key document, certificates for the host-key document
|
||||
verification, and an output file name. Optionally, specify an initial
|
||||
RAM filesystem, and a file containing the kernel parameters. If the
|
||||
command should be run offline, use the \fB\-\-offline\fR option and
|
||||
specify the certificate revocation lists (CRLs) by using the
|
||||
\fB\-\-crl\fR option. Should special circumstances require it, you can
|
||||
optionally specify your own keys for the encryption by using the
|
||||
experimental options. In the resulting image file, a plain text boot
|
||||
loader, the encrypted components for kernel, initial RAM disk, kernel
|
||||
parameters, and the encrypted and integrity-protected header are
|
||||
concatenated. The header contains metadata necessary for running the
|
||||
guest in protected mode.
|
||||
experimental options. For all certificates, CRLs, and host-key
|
||||
documents, both the PEM and DER input formats are supported. In the
|
||||
resulting image file, a plain text boot loader, the encrypted
|
||||
components for kernel, initial RAM disk, kernel parameters, and the
|
||||
encrypted and integrity-protected header are concatenated. The header
|
||||
contains metadata necessary for running the guest in protected mode.
|
||||
.PP
|
||||
Use this image file as a kernel image for zipl or for a direct kernel
|
||||
boot using QEMU.
|
||||
@@ -53,6 +58,12 @@ Specifies a host-key document. At least one is required. Specify this
|
||||
option multiple times to enable the image to run on more than one
|
||||
host.
|
||||
.TP
|
||||
\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR
|
||||
Specifies the certificate that is used to establish a chain of trust
|
||||
for the verification of the host-key documents. Specify this option
|
||||
twice to specify the IBM Z signing key and the intermediate CA
|
||||
certificate (signed by the root CA). Required.
|
||||
.TP
|
||||
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
|
||||
Specifies the output file. Required.
|
||||
.TP
|
||||
@@ -65,6 +76,20 @@ Specifies the RAM disk image. Optional.
|
||||
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
|
||||
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
|
||||
.TP
|
||||
\fB\-\-crl\fR=\fI\,FILE\/\fR
|
||||
Specifies the revocation list that is used to check whether a
|
||||
certificate of the chain of trust is revoked. Specify this option
|
||||
multiple times to use multiple CRLs. Optional.
|
||||
.TP
|
||||
\fB\-\-offline\fR
|
||||
Specifies offline mode, in which no attempt is made to download
|
||||
CRLs. Optional.
|
||||
.TP
|
||||
\fB\-\-root\-ca\fR=\fI\,FILE\/\fR
|
||||
Specifies the root CA certificate for the verification. If omitted,
|
||||
the DigiCert root CA certificate installed on the system is used. Use
|
||||
this only if you trust the specified certificate. Optional.
|
||||
.TP
|
||||
\fB\-\-no-verify\fR
|
||||
Do not require the host-key documents to be valid. For testing
|
||||
purposes, do not use for a production image. Optional.
|
||||
@@ -77,11 +102,13 @@ Prints version information, then exits.
|
||||
Generate a protected virtualization image in
|
||||
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
|
||||
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
|
||||
\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR:
|
||||
\fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR,
|
||||
the IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the
|
||||
host-key document in \fI\,host_key.crt\/\fR:
|
||||
.PP
|
||||
.Vb 1
|
||||
.EX
|
||||
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR
|
||||
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt \-o \fI\,/boot/vmlinuz.pv\/\fR
|
||||
.EE
|
||||
.Ve
|
||||
.PP
|
||||
|
||||
@@ -23,16 +23,16 @@ WARNINGS := -Wall -Wextra -Wshadow \
|
||||
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
|
||||
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
|
||||
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
|
||||
pv/pv_opt_item.c \
|
||||
pv/pv_opt_item.c utils/curl.c \
|
||||
$(NULL)
|
||||
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
|
||||
|
||||
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
|
||||
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \
|
||||
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \
|
||||
$(WARNINGS) \
|
||||
$(NULL)
|
||||
ALL_CPPFLAGS += $(INCLUDE_PARMS)
|
||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
|
||||
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
|
||||
|
||||
|
||||
ifneq ($(shell sh -c 'command -v pkg-config'),)
|
||||
@@ -40,21 +40,27 @@ GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
|
||||
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
|
||||
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
|
||||
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
|
||||
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
|
||||
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
|
||||
else
|
||||
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
|
||||
GLIB2_LIBS := -lglib-2.0
|
||||
LIBCRYPTO_CFLAGS :=
|
||||
LIBCRYPTO_LIBS := -lcrypto
|
||||
LIBCURL_CFLAGS :=
|
||||
LIBCURL_LIBS := -lcurl
|
||||
endif
|
||||
|
||||
BUILD_TARGETS := skip-$(bin_PROGRAM)
|
||||
INSTALL_TARGETS := skip-$(bin_PROGRAM)
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
ifneq (${HAVE_GLIB2},0)
|
||||
ifneq (${HAVE_LIBCURL},0)
|
||||
BUILD_TARGETS := $(bin_PROGRAM)
|
||||
INSTALL_TARGETS := install-$(bin_PROGRAM)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
all: $(BUILD_TARGETS)
|
||||
|
||||
@@ -98,4 +104,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM)
|
||||
"openssl-devel / libssl-dev version >= 1.1.0", \
|
||||
"HAVE_OPENSSL=0", \
|
||||
"-I.")
|
||||
$(call check_dep, \
|
||||
"$(bin_PROGRAM)", \
|
||||
"curl/curl.h", \
|
||||
"libcurl-devel", \
|
||||
"HAVE_LIBCURL=0")
|
||||
touch $@
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "common.h"
|
||||
#include "pv/pv_args.h"
|
||||
#include "pv/pv_image.h"
|
||||
#include "utils/crypto.h"
|
||||
#include "utils/curl.h"
|
||||
|
||||
enum {
|
||||
LOG_LEVEL_CRITICAL = 0,
|
||||
@@ -117,6 +119,8 @@ static void remove_signal_handler(const gint *signals, const gsize signals_n)
|
||||
signal(signals[i], SIG_DFL);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor)) __init(void);
|
||||
static void __attribute__((destructor)) __cleanup(void);
|
||||
gint main(gint argc, gchar *argv[])
|
||||
{
|
||||
g_autoptr(PvArgs) args = pv_args_new();
|
||||
@@ -177,5 +181,20 @@ error:
|
||||
rmdir_recursive(tmp_dir, NULL);
|
||||
remove_signal_handler(signals, G_N_ELEMENTS(signals));
|
||||
g_free(tmp_dir);
|
||||
g_clear_pointer(&img, pv_img_free);
|
||||
g_clear_pointer(&args, pv_args_free);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
static void __init(void)
|
||||
{
|
||||
pv_crypto_init();
|
||||
if (curl_init() != 0)
|
||||
g_abort();
|
||||
}
|
||||
|
||||
static void __cleanup(void)
|
||||
{
|
||||
curl_cleanup();
|
||||
pv_crypto_cleanup();
|
||||
}
|
||||
|
||||
@@ -14,6 +14,24 @@
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
/* IBM signing key subject */
|
||||
#define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation"
|
||||
#define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US"
|
||||
#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie"
|
||||
#define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service"
|
||||
#define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation"
|
||||
#define PV_IBM_Z_SUBJECT_STATE "New York"
|
||||
#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6
|
||||
|
||||
/* Minimum security level for the keys/certificates used to establish a chain of
|
||||
* trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html
|
||||
* for details).
|
||||
*/
|
||||
#define PV_CERTS_SECURITY_LEVEL 2
|
||||
|
||||
/* SKID for DigiCert Assured ID Root CA */
|
||||
#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F"
|
||||
|
||||
union ecdh_pub_key {
|
||||
struct {
|
||||
uint8_t x[80];
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
static gchar summary[] =
|
||||
"Use genprotimg to create a protected virtualization kernel image file,\n"
|
||||
"which can be loaded using zipl or QEMU.";
|
||||
"which can be loaded using zipl or QEMU. For all certificates, revocation\n"
|
||||
"lists, and host-key documents, both the PEM and DER input formats are\n"
|
||||
"supported.";
|
||||
|
||||
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
|
||||
{
|
||||
@@ -97,9 +99,14 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!args->no_verify) {
|
||||
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
|
||||
_("Use the option '--no-verify' as the verification support is not available yet."));
|
||||
if (!args->no_verify &&
|
||||
(!args->untrusted_cert_paths ||
|
||||
g_strv_length(args->untrusted_cert_paths) == 0)) {
|
||||
g_set_error(
|
||||
err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
|
||||
_("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n"
|
||||
"by using the '--cert' option, or use the '--no-verify' flag to disable the\n"
|
||||
"host-key document verification completely (at your own risk)."));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -141,6 +148,8 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value,
|
||||
{
|
||||
gchar **args_option = NULL;
|
||||
|
||||
if (g_str_equal(option, "--root-ca"))
|
||||
args_option = &args->root_ca_path;
|
||||
if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
|
||||
args_option = &args->output_path;
|
||||
if (g_str_equal(option, "--x-comp-key"))
|
||||
@@ -211,6 +220,18 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
||||
_("FILE specifies a host-key document. At least\n" INDENT
|
||||
"one is required."),
|
||||
.arg_description = _("FILE") },
|
||||
{ .long_name = "cert",
|
||||
.short_name = 'C',
|
||||
.flags = G_OPTION_FLAG_NONE,
|
||||
.arg = G_OPTION_ARG_FILENAME_ARRAY,
|
||||
.arg_data = &args->untrusted_cert_paths,
|
||||
.description = _(
|
||||
"FILE contains a certificate that is used to\n" INDENT
|
||||
"establish a chain of trust for the verification\n" INDENT
|
||||
"of the host-key documents. The IBM Z signing\n" INDENT
|
||||
"key and intermediate CA certificate (signed\n" INDENT
|
||||
"by the root CA) are required."),
|
||||
.arg_description = _("FILE") },
|
||||
{ .long_name = "output",
|
||||
.short_name = 'o',
|
||||
.flags = G_OPTION_FLAG_FILENAME,
|
||||
@@ -227,7 +248,7 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
||||
.arg_description = _("IMAGE") },
|
||||
{ .long_name = "ramdisk",
|
||||
.short_name = 'r',
|
||||
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
|
||||
.flags = G_OPTION_FLAG_FILENAME,
|
||||
.arg = G_OPTION_ARG_CALLBACK,
|
||||
.arg_data = cb_add_component,
|
||||
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT
|
||||
@@ -235,12 +256,37 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
|
||||
.arg_description = _("RAMDISK") },
|
||||
{ .long_name = "parmfile",
|
||||
.short_name = 'p',
|
||||
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
|
||||
.flags = G_OPTION_FLAG_FILENAME,
|
||||
.arg = G_OPTION_ARG_CALLBACK,
|
||||
.arg_data = cb_add_component,
|
||||
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
|
||||
"(optional)."),
|
||||
.arg_description = _("PARMFILE") },
|
||||
{ .long_name = "crl",
|
||||
.short_name = 0,
|
||||
.flags = G_OPTION_FLAG_NONE,
|
||||
.arg = G_OPTION_ARG_FILENAME_ARRAY,
|
||||
.arg_data = &args->crl_paths,
|
||||
.description = _(
|
||||
"FILE contains a certificate revocation list\n" INDENT
|
||||
"(optional)."),
|
||||
.arg_description = _("FILE") },
|
||||
{ .long_name = "offline",
|
||||
.short_name = 0,
|
||||
.flags = G_OPTION_FLAG_NONE,
|
||||
.arg = G_OPTION_ARG_NONE,
|
||||
.arg_data = &args->offline,
|
||||
.description = _("Don't download CRLs (optional)."),
|
||||
.arg_description = NULL },
|
||||
{ .long_name = "root-ca",
|
||||
.short_name = 0,
|
||||
.flags = G_OPTION_FLAG_FILENAME,
|
||||
.arg = G_OPTION_ARG_CALLBACK,
|
||||
.arg_data = cb_set_string_option,
|
||||
.description = _(
|
||||
"Set FILE as the trusted root CA and don't use the\n" INDENT
|
||||
"root CAs that are installed on the system (optional)."),
|
||||
.arg_description = _("FILE") },
|
||||
{ .long_name = "no-verify",
|
||||
.short_name = 0,
|
||||
.flags = G_OPTION_FLAG_NONE,
|
||||
@@ -378,6 +424,9 @@ void pv_args_free(PvArgs *args)
|
||||
g_free(args->cust_root_key_path);
|
||||
g_free(args->cust_comm_key_path);
|
||||
g_free(args->gcm_iv_path);
|
||||
g_free(args->root_ca_path);
|
||||
g_strfreev(args->crl_paths);
|
||||
g_strfreev(args->untrusted_cert_paths);
|
||||
g_strfreev(args->host_keys);
|
||||
g_free(args->xts_key_path);
|
||||
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);
|
||||
|
||||
@@ -25,6 +25,7 @@ void pv_arg_free(PvArg *arg);
|
||||
typedef struct {
|
||||
gint log_level;
|
||||
gint no_verify;
|
||||
gboolean offline;
|
||||
gchar *pcf;
|
||||
gchar *scf;
|
||||
gchar *psw_addr; /* PSW address which will be used for the start of
|
||||
@@ -34,6 +35,11 @@ typedef struct {
|
||||
gchar *cust_comm_key_path;
|
||||
gchar *gcm_iv_path;
|
||||
gchar **host_keys;
|
||||
gchar *root_ca_path; /* Trusted root CA used for the verification of the
|
||||
* chain of trust (if specified).
|
||||
*/
|
||||
gchar **untrusted_cert_paths;
|
||||
gchar **crl_paths;
|
||||
gchar *xts_key_path;
|
||||
GSList *comps;
|
||||
gchar *output_path;
|
||||
|
||||
@@ -28,6 +28,8 @@ typedef enum {
|
||||
PV_ERROR_IPIB_SIZE,
|
||||
PV_ERROR_PV_HDR_SIZE,
|
||||
PV_ERROR_INTERNAL,
|
||||
PV_ERROR_CURL_INIT_FAILED,
|
||||
PV_ERROR_DOWNLOAD_FAILED,
|
||||
} PvErrors;
|
||||
|
||||
typedef enum {
|
||||
@@ -57,6 +59,31 @@ typedef enum {
|
||||
PV_CRYPTO_ERROR_RANDOMIZATION,
|
||||
PV_CRYPTO_ERROR_INVALID_PARM,
|
||||
PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
|
||||
PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD,
|
||||
PV_CRYPTO_ERROR_EXPIRED,
|
||||
PV_CRYPTO_ERROR_NOT_VALID_YET,
|
||||
PV_CRYPTO_ERROR_LOAD_CRL,
|
||||
PV_CRYPTO_ERROR_NO_PUBLIC_KEY,
|
||||
PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM,
|
||||
PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH,
|
||||
PV_CRYPTO_ERROR_INVALID_URI,
|
||||
PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED,
|
||||
PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID,
|
||||
PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID,
|
||||
PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH,
|
||||
PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH,
|
||||
PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||
PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE,
|
||||
PV_CRYPTO_ERROR_NO_CRL,
|
||||
PV_CRYPTO_ERROR_LOAD_ROOT_CA,
|
||||
PV_CRYPTO_ERROR_LOAD_DEFAULT_CA,
|
||||
PV_CRYPTO_ERROR_MALFORMED_ROOT_CA,
|
||||
PV_CRYPTO_ERROR_WRONG_CA_USED,
|
||||
PV_CRYPTO_ERROR_SKID_AKID_MISMATCH,
|
||||
PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND,
|
||||
PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL,
|
||||
PV_CRYPTO_ERROR_NO_CRLDP,
|
||||
PV_CRYPTO_ERROR_CERT_REVOKED,
|
||||
} PvCryptoErrors;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <errno.h>
|
||||
#include <glib.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err)
|
||||
return generate_ec_key(nid, err);
|
||||
}
|
||||
|
||||
static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
|
||||
X509_STORE *store, gint nid,
|
||||
static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid,
|
||||
GError **err)
|
||||
{
|
||||
g_autoslist(EVP_PKEY) ret = NULL;
|
||||
|
||||
g_assert(host_cert_paths);
|
||||
|
||||
for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL;
|
||||
iterator++) {
|
||||
for (GSList *iterator = host_keys_with_path; iterator;
|
||||
iterator = iterator->next) {
|
||||
x509_with_path *cert_with_path = iterator->data;
|
||||
g_autoptr(EVP_PKEY) host_key = NULL;
|
||||
const gchar *path = *iterator;
|
||||
X509 *cert = cert_with_path->cert;
|
||||
|
||||
g_assert(path);
|
||||
|
||||
host_key = read_ec_pubkey_cert(store, nid, path, err);
|
||||
host_key = read_ec_pubkey_cert(cert, nid, err);
|
||||
if (!host_key)
|
||||
return NULL;
|
||||
|
||||
@@ -253,10 +250,172 @@ static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint pv_img_hostkey_verify(GSList *host_key_certs,
|
||||
const gchar *root_ca_path,
|
||||
const gchar *const *crl_paths,
|
||||
const gchar *const *untrusted_cert_paths,
|
||||
gboolean offline, GError **err)
|
||||
{
|
||||
g_autoslist(x509_with_path) untrusted_certs_with_path = NULL;
|
||||
g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL;
|
||||
g_autoptr(STACK_OF_X509) untrusted_certs = NULL;
|
||||
g_autoslist(x509_pair) ibm_z_pairs = NULL;
|
||||
g_autoptr(X509_STORE) trusted = NULL;
|
||||
gint ibm_signing_certs_count;
|
||||
|
||||
/* Load trusted root CAs of the system if and only if @root_ca_path is
|
||||
* NULL, otherwise use the root CA specified by @root_ca_path.
|
||||
*/
|
||||
trusted = store_setup(root_ca_path, crl_paths, err);
|
||||
if (!trusted)
|
||||
goto error;
|
||||
|
||||
if (!offline) {
|
||||
g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL;
|
||||
|
||||
/* Set up the download routine for the lookup of CRLs. */
|
||||
store_setup_crl_download(trusted);
|
||||
|
||||
/* Try to download the CRLs of the IBM Z signing certificates
|
||||
* specified in the host-key documents. Ignore download errors
|
||||
* as it's still possible that a CRL is specified via command
|
||||
* line.
|
||||
*/
|
||||
downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs);
|
||||
|
||||
/* Add the downloaded CRLs to the store so they can be used for
|
||||
* the verification later.
|
||||
*/
|
||||
for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) {
|
||||
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
|
||||
|
||||
if (X509_STORE_add_crl(trusted, crl) != 1) {
|
||||
g_set_error(err, PV_CRYPTO_ERROR,
|
||||
PV_CRYPTO_ERROR_INTERNAL,
|
||||
_("failed to load CRL"));
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Load all untrusted certificates (e.g. IBM Z signing key and
|
||||
* DigiCert intermediate CA) that are required to establish a chain of
|
||||
* trust starting from the host-key document up to the root CA (if not
|
||||
* otherwise specified that's the DigiCert Assured ID Root CA).
|
||||
*/
|
||||
untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err);
|
||||
if (!untrusted_certs_with_path)
|
||||
goto error;
|
||||
|
||||
/* Convert to STACK_OF(X509) */
|
||||
untrusted_certs = get_x509_stack(untrusted_certs_with_path);
|
||||
|
||||
/* Find all IBM Z signing keys and remove them from the chain as we
|
||||
* have to verify that they're valid. The last step of the chain of
|
||||
* trust verification must be done manually, as the IBM Z signing keys
|
||||
* are not marked as (intermediate) CA and therefore the standard
|
||||
* `X509_verify_cert` function of OpenSSL cannot be used to verify the
|
||||
* actual host-key documents.
|
||||
*/
|
||||
ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs);
|
||||
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
|
||||
if (ibm_signing_certs_count < 1) {
|
||||
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||
_("please specify at least one IBM Z signing key"));
|
||||
goto error;
|
||||
} else if (ibm_signing_certs_count > 1) {
|
||||
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
|
||||
_("please specify only one IBM Z signing key"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (store_set_verify_param(trusted, err) < 0)
|
||||
goto error;
|
||||
|
||||
/* Verify that the IBM Z signing keys are trustable.
|
||||
* For this we must check:
|
||||
*
|
||||
* 1. Can a chain of trust be established ending in a root CA
|
||||
* 2. Is the correct root CA ued? It has either to be the
|
||||
* 'DigiCert Assured ID Root CA' or the root CA specified via
|
||||
* command line.
|
||||
*/
|
||||
for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) {
|
||||
X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i);
|
||||
g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL;
|
||||
g_autoptr(X509_STORE_CTX) ctx = NULL;
|
||||
x509_pair *pair = NULL;
|
||||
|
||||
g_assert(ibm_signing_cert);
|
||||
|
||||
/* Create the verification context and set the trusted
|
||||
* and chain parameters.
|
||||
*/
|
||||
ctx = create_store_ctx(trusted, untrusted_certs, err);
|
||||
if (!ctx)
|
||||
goto error;
|
||||
|
||||
/* Verify the IBM Z signing key */
|
||||
if (verify_cert(ibm_signing_cert, ctx, err) < 0)
|
||||
goto error;
|
||||
|
||||
/* Verify the build chain of trust chain. If the user passes a
|
||||
* trusted root CA on the command line then the check for the
|
||||
* Subject Key Identifier (SKID) is skipped, otherwise let's
|
||||
* check if the SKID meets our expectation.
|
||||
*/
|
||||
if (!root_ca_path &&
|
||||
check_chain_parameters(X509_STORE_CTX_get0_chain(ctx),
|
||||
get_digicert_assured_id_root_ca_skid(),
|
||||
err) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err);
|
||||
if (!ibm_signing_crls) {
|
||||
g_prefix_error(err, _("IBM Z signing key: "));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Increment reference counter of @ibm_signing_cert as the
|
||||
* certificate will now also be owned by @ibm_z_pairs.
|
||||
*/
|
||||
if (X509_up_ref(ibm_signing_cert) != 1)
|
||||
g_abort();
|
||||
|
||||
pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls);
|
||||
ibm_z_pairs = g_slist_append(ibm_z_pairs, pair);
|
||||
g_assert(!ibm_signing_cert);
|
||||
g_assert(!ibm_signing_crls);
|
||||
}
|
||||
|
||||
/* Verify host-key documents by using the IBM Z signing
|
||||
* certificates and the corresponding certificate revocation
|
||||
* lists.
|
||||
*/
|
||||
for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) {
|
||||
x509_with_path *host_key_with_path = iterator->data;
|
||||
const gchar *host_key_path = host_key_with_path->path;
|
||||
X509 *host_key = host_key_with_path->cert;
|
||||
gint flags = X509_V_FLAG_CRL_CHECK;
|
||||
|
||||
if (verify_host_key(host_key, ibm_z_pairs, flags,
|
||||
PV_CERTS_SECURITY_LEVEL, err) < 0) {
|
||||
g_prefix_error(err, "'%s': ", host_key_path);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
g_prefix_error(err, _("Failed to verify host-key document: "));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read in the keys or auto-generate them */
|
||||
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
|
||||
{
|
||||
g_autoptr(X509_STORE) store = NULL;
|
||||
g_autoslist(x509_with_path) host_key_certs = NULL;
|
||||
|
||||
g_assert(img->xts_cipher);
|
||||
g_assert(img->cust_comm_cipher);
|
||||
@@ -285,8 +444,25 @@ static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
|
||||
if (!img->cust_pub_priv_key)
|
||||
return -1;
|
||||
|
||||
/* Load all host-key documents specified on the command line */
|
||||
host_key_certs = load_certificates((const gchar **)args->host_keys,
|
||||
err);
|
||||
if (!host_key_certs)
|
||||
return -1;
|
||||
|
||||
if (!args->no_verify &&
|
||||
pv_img_hostkey_verify(host_key_certs, args->root_ca_path,
|
||||
(const gchar * const *)args->crl_paths,
|
||||
(const gchar * const *)args->untrusted_cert_paths,
|
||||
args->offline, err) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Loads the public keys stored in the host-key documents and verify
|
||||
* that the correct elliptic curve is used.
|
||||
*/
|
||||
img->host_pub_keys =
|
||||
pv_img_get_host_keys(args->host_keys, store, img->nid, err);
|
||||
pv_img_get_host_keys(host_key_certs, img->nid, err);
|
||||
if (!img->host_pub_keys)
|
||||
return -1;
|
||||
|
||||
@@ -406,6 +582,9 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
|
||||
if (args->no_verify)
|
||||
g_warning(_("host-key document verification is disabled. Your workload is not secured."));
|
||||
|
||||
if (args->root_ca_path)
|
||||
g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted."));
|
||||
|
||||
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
|
||||
if (!ret->comps)
|
||||
return NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,14 +11,18 @@
|
||||
#define PV_UTILS_CRYPTO_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdh.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/safestack.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "common.h"
|
||||
@@ -33,6 +37,9 @@
|
||||
#define AES_256_XTS_TWEAK_SIZE 16
|
||||
#define AES_256_XTS_KEY_SIZE 64
|
||||
|
||||
#define CRL_DOWNLOAD_TIMEOUT_MS 3000
|
||||
#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */
|
||||
|
||||
enum PvCryptoMode {
|
||||
PV_ENCRYPT,
|
||||
PV_DECRYPT,
|
||||
@@ -40,7 +47,34 @@ enum PvCryptoMode {
|
||||
|
||||
typedef GSList HostKeyList;
|
||||
|
||||
/* play nice with g_autoptr */
|
||||
typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT;
|
||||
typedef STACK_OF(X509) STACK_OF_X509;
|
||||
typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL;
|
||||
|
||||
void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack);
|
||||
void STACK_OF_X509_free(STACK_OF_X509 *stack);
|
||||
void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack);
|
||||
|
||||
typedef struct {
|
||||
X509 *cert;
|
||||
const gchar *path;
|
||||
} x509_with_path;
|
||||
|
||||
x509_with_path *x509_with_path_new(X509 *cert, const gchar *path);
|
||||
void x509_with_path_free(x509_with_path *cert);
|
||||
|
||||
typedef struct {
|
||||
X509 *cert;
|
||||
STACK_OF_X509_CRL *crls;
|
||||
} x509_pair;
|
||||
|
||||
x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls);
|
||||
void x509_pair_free(x509_pair *pair);
|
||||
|
||||
/* Register auto cleanup functions */
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
|
||||
@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free);
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free);
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free);
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free)
|
||||
|
||||
union cmp_index {
|
||||
struct {
|
||||
@@ -79,8 +121,37 @@ struct cipher_parms {
|
||||
const Buffer *iv_or_tweak;
|
||||
};
|
||||
|
||||
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path,
|
||||
GError **err);
|
||||
int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert,
|
||||
gint verify_flags, GError **err);
|
||||
void pv_crypto_init(void);
|
||||
void pv_crypto_cleanup(void);
|
||||
const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void);
|
||||
gint verify_host_key(X509 *host_key, GSList *issuer_pairs,
|
||||
gint verify_flags, int level, GError **err);
|
||||
X509 *load_cert_from_file(const char *path, GError **err);
|
||||
X509_CRL *load_crl_from_file(const gchar *path, GError **err);
|
||||
GSList *load_certificates(const gchar *const *cert_paths, GError **err);
|
||||
STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list);
|
||||
X509_STORE *store_setup(const gchar *root_ca_path,
|
||||
const gchar * const *crl_paths,
|
||||
GError **err);
|
||||
int store_set_verify_param(X509_STORE *store, GError **err);
|
||||
X509_CRL *load_crl_by_cert(X509 *cert, GError **err);
|
||||
STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path);
|
||||
gint check_chain_parameters(const STACK_OF_X509 *chain,
|
||||
const ASN1_OCTET_STRING *skid, GError **err);
|
||||
X509_NAME *c2b_name(const X509_NAME *name);
|
||||
|
||||
STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs);
|
||||
STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert,
|
||||
GError **err);
|
||||
X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain,
|
||||
GError **err);
|
||||
gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err);
|
||||
X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err);
|
||||
void store_setup_crl_download(X509_STORE *st);
|
||||
EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err);
|
||||
|
||||
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
|
||||
Buffer *generate_aes_key(guint size, GError **err);
|
||||
Buffer *generate_aes_iv(guint size, GError **err);
|
||||
|
||||
121
genprotimg/src/utils/curl.c
Normal file
121
genprotimg/src/utils/curl.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Libcurl utils
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gtypes.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "pv/pv_error.h"
|
||||
|
||||
#include "curl.h"
|
||||
|
||||
struct UserData {
|
||||
GByteArray *buffer;
|
||||
guint max_size;
|
||||
};
|
||||
|
||||
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
g_assert(userdata);
|
||||
struct UserData *data = (struct UserData *)userdata;
|
||||
GByteArray *buffer = data->buffer;
|
||||
guint64 actual_size;
|
||||
size_t err;
|
||||
|
||||
g_assert(buffer);
|
||||
|
||||
if (!g_uint64_checked_mul(&actual_size, size, nmemb))
|
||||
g_abort();
|
||||
|
||||
/* Signal an error condition by returning a amount that differs
|
||||
* from the amount passed to the callback. This results in a
|
||||
* CURLE_WRITE_ERROR.
|
||||
*/
|
||||
err = actual_size + 1;
|
||||
|
||||
if (actual_size > G_MAXUINT)
|
||||
return err;
|
||||
|
||||
data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size);
|
||||
if (data->buffer->len > data->max_size)
|
||||
return err;
|
||||
|
||||
return actual_size;
|
||||
}
|
||||
|
||||
gint curl_init(void)
|
||||
{
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void curl_cleanup(void)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
|
||||
GError **err)
|
||||
{
|
||||
g_autoptr(GByteArray) ret = NULL;
|
||||
g_autoptr(CURL) handle = NULL;
|
||||
g_autofree gchar *agent = NULL;
|
||||
struct UserData userdata;
|
||||
CURLcode rc;
|
||||
|
||||
/* set up curl session */
|
||||
handle = curl_easy_init();
|
||||
if (!handle)
|
||||
g_abort();
|
||||
|
||||
/* follow redirection */
|
||||
rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING);
|
||||
rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
ret = g_byte_array_new();
|
||||
userdata.buffer = ret;
|
||||
userdata.max_size = max_size;
|
||||
rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
rc = curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||
if (rc != CURLE_OK)
|
||||
goto curl_err;
|
||||
|
||||
rc = curl_easy_perform(handle);
|
||||
if (rc != CURLE_OK) {
|
||||
g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED,
|
||||
_("download failed: %s"), curl_easy_strerror(rc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_steal_pointer(&ret);
|
||||
curl_err:
|
||||
g_set_error(err, PV_ERROR,
|
||||
PV_ERROR_CURL_INIT_FAILED,
|
||||
_("cURL initialization failed: %s"),
|
||||
curl_easy_strerror(rc));
|
||||
return NULL;
|
||||
}
|
||||
25
genprotimg/src/utils/curl.h
Normal file
25
genprotimg/src/utils/curl.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Libcurl utils
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef PV_UTILS_LIBCURL_H
|
||||
#define PV_UTILS_LIBCURL_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup)
|
||||
|
||||
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
|
||||
GError **err);
|
||||
gint curl_init(void);
|
||||
void curl_cleanup(void);
|
||||
|
||||
#endif /* PV_UTILS_LIBCURL_H */
|
||||
16
hsci/Makefile
Normal file
16
hsci/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
include ../common.mak
|
||||
|
||||
all:
|
||||
|
||||
install: hsci
|
||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
|
||||
chmod 755 $(DESTDIR)$(BINDIR)/hsci; \
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \
|
||||
$(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
clean:
|
||||
|
||||
.PHONY: all install clean
|
||||
441
hsci/hsci
Executable file
441
hsci/hsci
Executable file
@@ -0,0 +1,441 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# hsci - Tool to manage HiperSockets Converged Interfaces (HSCI)
|
||||
#
|
||||
# Copyright IBM Corp. 2020
|
||||
#
|
||||
# s390-tools is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the MIT license. See LICENSE for details.
|
||||
#
|
||||
|
||||
hsdev=""
|
||||
ndev=""
|
||||
hsci=""
|
||||
hsdev_mac=""
|
||||
hsif_pnetid=""
|
||||
netif_pnetid=""
|
||||
hsci_pnetid=""
|
||||
|
||||
function usage {
|
||||
cat <<-EOD
|
||||
Usage: hsci COMMAND [OPTION]
|
||||
|
||||
This tool is designed to control and show HSCI (HiperSockets Converged
|
||||
Interfaces) settings. A HiperSockets interface and an external network
|
||||
|
||||
COMMANDS
|
||||
add HIPERSOCKETS_DEV NET_DEV Adds an HSCI interface
|
||||
del HSCI_NAME Deletes an HSCI interface
|
||||
show Lists the configured HSCI interfaces
|
||||
|
||||
OPTIONS:
|
||||
-v, --version Prints the version number of the hsci tool and exits
|
||||
-h, --help Displays the help information for the command
|
||||
EOD
|
||||
}
|
||||
|
||||
function prereqs_check {
|
||||
if ! [ -x "$(command -v ip)" ]; then
|
||||
echo "Error: No iproute2 installed on this system" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
function check_pnetids {
|
||||
# get PNETID of the HS
|
||||
local hsif_pnetids=""
|
||||
local netif_pnetids=""
|
||||
|
||||
if [ -e /sys/class/net/$hsdev/device/util_string ]; then
|
||||
hsif_pnetids="$(cat /sys/class/net/$hsdev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||
else
|
||||
if [ -e /sys/class/net/$hsdev/device/chpid ]; then
|
||||
chpid="$(cat /sys/class/net/$hsdev/device/chpid | tr [:upper:] [:lower:])"
|
||||
hsif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||
fi
|
||||
fi
|
||||
if [ "$hsif_pnetids" != "" ]; then
|
||||
port_hsif="$(cat /sys/class/net/$hsdev/dev_port)"
|
||||
(( idx=16*$port_hsif+1 ))
|
||||
(( end=$idx+15 ))
|
||||
hsif_pnetid="$(echo "$hsif_pnetids" | cut -c $idx-$end | tr -d ' ')"
|
||||
fi
|
||||
|
||||
# get PNETID of the NET_DEV
|
||||
if [ -e /sys/class/net/$ndev/device/util_string ]; then
|
||||
netif_pnetids="$(cat /sys/class/net/$ndev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||
else
|
||||
if [ -e /sys/class/net/$ndev/device/chpid ]; then
|
||||
chpid="$(cat /sys/class/net/$ndev/device/chpid | tr [:upper:] [:lower:])"
|
||||
netif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
|
||||
fi
|
||||
fi
|
||||
if [ "$netif_pnetids" != "" ]; then
|
||||
port_netif="$(cat /sys/class/net/$ndev/dev_port)"
|
||||
(( idx=16*$port_netif+1 ))
|
||||
(( end=$idx+15 ))
|
||||
netif_pnetid="$(echo "$netif_pnetids" | cut -c $idx-$end | tr -d ' ')"
|
||||
fi
|
||||
|
||||
#Check PNETIDs
|
||||
if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" != "$hsif_pnetid" ]; then
|
||||
echo "Error: $hsdev and $ndev have different PNETIDs! They are $hsif_pnetid and $netif_pnetid respectively" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" == "$hsif_pnetid" ]; then
|
||||
hsci_pnetid=$hsif_pnetid
|
||||
fi
|
||||
}
|
||||
|
||||
function verify_precon {
|
||||
echo "Verifying net dev $ndev and HiperSockets dev $hsdev"
|
||||
|
||||
if [ ! -e /sys/class/net/$hsdev ]; then
|
||||
echo "Error: $hsdev does not exist" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ "$(cat /sys/class/net/$hsdev/device/card_type)" != "HiperSockets" ]; then
|
||||
echo "Error: $hsdev is not a HiperSockets device" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ "$(cat /sys/class/net/$hsdev/device/layer2)" != "1" ]; then
|
||||
echo "Error: $hsdev is not in layer 2 mode" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ ! -e /sys/class/net/$hsdev/device/vnicc/bridge_invisible ]; then
|
||||
echo "Error: Missing vnic-characteristics support" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ "$(cat /sys/class/net/$hsdev/device/vnicc/bridge_invisible)" == "n/a" ]; then
|
||||
echo "Error: $hsdev does not support vnicc" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ $(ip link show $hsdev | grep UP | wc -l) -eq 0 ]; then
|
||||
echo "Error: $hsdev is not in state UP" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ $(bridge -d link show dev $hsdev self | grep learning_sync | wc -l) -eq 0 ]; then
|
||||
echo "Error: $hsdev does not support attribute learning_sync" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ $(ip link show $hsdev | grep master | wc -l) -ne 0 ]; then
|
||||
echo "Error: $hsdev is already a bridge port" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
#Pre-verify net_dev
|
||||
if [ ! -e /sys/class/net/$ndev ]; then
|
||||
echo "Error: $ndev does not exist" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ "$(cat /sys/class/net/$ndev/device/card_type)" == "HiperSockets" ]; then
|
||||
echo "Error: $ndev is also a HiperSockets device" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ $(ip link show $ndev | grep UP | wc -l) -eq 0 ]; then
|
||||
echo "Error: $ndev is not in state UP" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ $(ip link show $ndev | grep master | wc -l) -ne 0 ]; then
|
||||
echo "Error: $ndev is already a bridge port" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
#Check PNETIDs
|
||||
check_pnetids
|
||||
if [ $? -ne 0 ]; then
|
||||
return $?
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function clean_up {
|
||||
bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1
|
||||
echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible >/dev/null 2>&1
|
||||
bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1
|
||||
ip link del $hsci >/dev/null 2>&1
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
## add a new HSCI interface
|
||||
##############################################################################
|
||||
function add_hsci {
|
||||
|
||||
if [ $# != 2 ]; then
|
||||
echo "hsci: Invalid parameters" >&2
|
||||
echo "Use 'hsci --help' for more information" >&2
|
||||
return 1
|
||||
fi
|
||||
hsdev=$1
|
||||
ndev=$2
|
||||
|
||||
#### Verify preconditions
|
||||
verify_precon
|
||||
if [ $? -ne 0 ]; then
|
||||
return $?
|
||||
fi
|
||||
|
||||
hsci_postfix="$(readlink /sys/class/net/$hsdev/device/cdev0 | tail -c5)"
|
||||
hsci=hsci$hsci_postfix
|
||||
|
||||
echo "Adding $hsci with a HiperSockets dev $hsdev and an external dev $ndev"
|
||||
|
||||
#### Create bridge
|
||||
ip link add name $hsci type bridge stp_state 0 >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not create a bridge" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
#### Prepare hsdev
|
||||
# Set VNICC of hsdev to invisible
|
||||
#(mandatory for co-existence with HS-OSA bridges!)
|
||||
echo 1 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible
|
||||
|
||||
#### Create bridge ports
|
||||
ip link set dev $ndev master $hsci >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not set master for $ndev" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
ip link set dev $hsdev master $hsci >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Could not set master for $hsdev" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
|
||||
# no forwarding between ndev and hsdev -> isolated on
|
||||
# ndev is default for outgoing unknown targets -> flood on
|
||||
# no need to learn external LAN targets into fdb -> learning off
|
||||
bridge link set dev $ndev isolated on learning off flood on mcast_flood on >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to set bridge attributes on $ndev" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
|
||||
# no forwarding between ndev and hsdev -> isolated on
|
||||
# fdb will be populated by dev-to-bridge-notification, no need to learn
|
||||
# -> learning off
|
||||
# only send to hsdev, if listed in fdb -> flood off
|
||||
# don't send MC/BC on hsdev -> mcast_flood off
|
||||
bridge link set dev $hsdev isolated on learning off flood off mcast_flood off >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to set bridge attributes on $hsdev" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
|
||||
# NOTE: Although not required, BCs will be sent out on hsdev.
|
||||
# NOTE: We need to receive BCs on hsdev, as z/OS HSCI does ARP requests on HS.
|
||||
|
||||
hsdev_mac="$(cat /sys/class/net/$hsdev/address)"
|
||||
echo "Set $hsdev MAC $hsdev_mac on $ndev and $hsci"
|
||||
|
||||
# set HS MAC on OSA as secondary MAC
|
||||
bridge fdb add $hsdev_mac dev $ndev >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to set HS MAC on OSA as secondary MAC" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
|
||||
# set HS MAC (common MAC) on HSCI as primary MAC
|
||||
ip link set address $hsdev_mac dev $hsci >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to set HiperSockets MAC (common MAC) on HSCI as primary MAC" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
|
||||
# use hsdev MTU
|
||||
if [ -e /sys/class/net/$hsdev/mtu ]; then
|
||||
hs_mtu="$(cat /sys/class/net/$hsdev/mtu)"
|
||||
ip link set dev $hsci mtu $hs_mtu >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to set MTU for $hsci " >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
ip link set dev $hsci up >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to set $hsci up" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Turn on device for bridge notification
|
||||
bridge link set dev $hsdev learning_sync on self >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to turn on device for bridge notification" >&2
|
||||
clean_up
|
||||
return 1
|
||||
fi
|
||||
echo "Successfully added HSCI interface $hsci"
|
||||
return 0
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
## Delete HSCI
|
||||
##############################################################################
|
||||
|
||||
function del_hsci {
|
||||
if [ $# != 1 ]; then
|
||||
echo "hsci: invalid parameters" >&2
|
||||
echo "Use 'hsci --help' for more information" >&2
|
||||
return 1
|
||||
fi
|
||||
hsci=$1
|
||||
if [ $(ip link show dev $hsci | wc -l) -eq 0 ]; then
|
||||
echo "Error: $hsci does not exit" >&2
|
||||
return 1
|
||||
fi
|
||||
if [ $(ip link show | grep "master $hsci" | wc -l) -eq 0 ]; then
|
||||
echo "Error: $hsci is not an active HSCI interface" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
bports="$(ip link show | grep "master $hsci" | awk '{print $2}')"
|
||||
for bport in $bports; do
|
||||
if [ $(bridge -d link show dev $bport | grep "learning_sync on" | wc -l) -ne 0 ]; then
|
||||
hsdev=${bport%:}
|
||||
else
|
||||
ndev=${bport%:}
|
||||
fi
|
||||
done
|
||||
if [ "$hsdev" == "" ]; then
|
||||
echo "Error: $hsci has no active HiperSockets port" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "Deleting HSCI interface $hsci with the HiperSockets $hsdev and the external $ndev"
|
||||
|
||||
bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to turn off learning_sync on $hsdev" >&2
|
||||
return 1
|
||||
fi
|
||||
echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible
|
||||
|
||||
hsdev_mac="$(cat /sys/class/net/$hsdev/address)"
|
||||
echo "Deleting $hsev MAC $hsdev_mac on $ndev"
|
||||
bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to delete $hsev MAC $hsdev_mac on $ndev" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
ip link del $hsci >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Failed to delete $hsci" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "Successfully deleted device $hsci"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
## Show HSCI
|
||||
##############################################################################
|
||||
|
||||
function list_active {
|
||||
hsdev=$1
|
||||
local ext=""
|
||||
|
||||
hsci="$(ip link show dev $hsdev | awk '{for(x=1;x<NF;x++) if($x~/master/) print $(x+1)}')"
|
||||
ext="$(ip link show | grep "master $hsci" | grep --invert-match $hsdev | awk '{print $2}')"
|
||||
# remove trailing ':'
|
||||
ndev="${ext%:}"
|
||||
|
||||
check_pnetids
|
||||
|
||||
printf '%-8s %-16s %-15s %-15s\n' "$hsci" "$hsci_pnetid" "$hsdev" "$ndev"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function print_header {
|
||||
if [ $header -eq 0 ]; then
|
||||
echo "HSCI PNET_ID HiperSockets External "
|
||||
echo "------------------------------------------------------------"
|
||||
fi
|
||||
}
|
||||
|
||||
function list_one {
|
||||
local hsnetdev=$1
|
||||
|
||||
if [ $(bridge -d link show dev $hsnetdev | grep "learning_sync on" | wc -l) -ne 0 ]; then
|
||||
print_header
|
||||
list_active $hsnetdev
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function show_hsci {
|
||||
if [ $# != 0 ]; then
|
||||
echo "hsci: invalid parameters" >&2
|
||||
echo "Use 'hsci --help' for more information" >&2
|
||||
return 1
|
||||
fi
|
||||
header=0
|
||||
|
||||
for hs_net_dev in $(ls -1 /sys/class/net/); do
|
||||
list_one $hs_net_dev
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
#==============================================================================
|
||||
|
||||
function print_version()
|
||||
{
|
||||
echo "hsci utility: version %S390_TOOLS_VERSION%"
|
||||
echo "Copyright IBM Corp. 2020"
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
##### Main
|
||||
##############################################################################
|
||||
prereqs_check
|
||||
|
||||
args="$(getopt -u -o hv -l help,version -- $*)"
|
||||
[ $? -ne 0 ] && exit 2
|
||||
set -- $args
|
||||
while true; do
|
||||
case $1 in
|
||||
-v | --version)
|
||||
print_version
|
||||
exit 0
|
||||
;;
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
;;
|
||||
add) shift
|
||||
add_hsci "$@"
|
||||
exit $?
|
||||
;;
|
||||
del) shift
|
||||
del_hsci "$@"
|
||||
exit $?
|
||||
;;
|
||||
show) shift
|
||||
show_hsci "$@"
|
||||
exit $?
|
||||
;;
|
||||
*) echo "hsci: Please specify a valid command or option" >&2
|
||||
echo "Use 'hsci --help' for more information" >&2
|
||||
exit 1
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
100
hsci/hsci.8
Normal file
100
hsci/hsci.8
Normal file
@@ -0,0 +1,100 @@
|
||||
.\" Copyright IBM Corp. 2020
|
||||
|
||||
.TH HSCI 8 "November 2020" "s390-tools" "Linux Programmer's Manual"
|
||||
|
||||
|
||||
.SH NAME
|
||||
.B hsci
|
||||
\- control and show HSCI settings.
|
||||
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B hsci add
|
||||
.I HSDEV
|
||||
.I NETDEV
|
||||
.br
|
||||
.B hsci del
|
||||
.I HSCINAME
|
||||
.br
|
||||
.B hsci show
|
||||
.br
|
||||
.B hsci [\-hv]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.BI hsci
|
||||
is used to control and show HSCI (HiperSockets Converged Interfaces) settings. A HiperSockets interface and an external network interface are converged into an HSCI interface.
|
||||
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.B add \fIHSDEV\fR \fINETDEV\fR
|
||||
.RS .4i
|
||||
.PP
|
||||
Adds an HSCI interface
|
||||
.PP
|
||||
.I HSDEV
|
||||
is the interface name of the HiperSockets device to be converged into the HSCI interface.
|
||||
.PP
|
||||
.I NETDEV
|
||||
is the interface name of the external network device to be converged into the HSCI interface.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B del \fIHSCINAME\fR
|
||||
.RS .4i
|
||||
.PP
|
||||
Deletes an HSCI interface
|
||||
.PP
|
||||
.I HSCINAME
|
||||
is the name of the HSCI interface for the HiperSockets device and the external network device.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B show
|
||||
.RS .4i
|
||||
.PP
|
||||
Lists the configured HSCI interfaces.
|
||||
.RE
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR \-v ", " \-\-version
|
||||
Prints the version number of hsci and exits.
|
||||
.TP
|
||||
.BR \-h ", " \-\-help
|
||||
Displays the help information for the command.
|
||||
|
||||
.SH EXIT CODES
|
||||
.TP
|
||||
.BR "0"
|
||||
The hsci command ran successfully.
|
||||
|
||||
.TP
|
||||
.BR "1"
|
||||
An error occurred.
|
||||
|
||||
.SH EXAMPLE
|
||||
.BR "hsci show"
|
||||
.TP
|
||||
.RB
|
||||
Lists the configured HSCI interfaces:
|
||||
.RS 1.2i
|
||||
|
||||
HSCI PNET_ID HiperSockets External
|
||||
.br
|
||||
-----------------------------------------
|
||||
.br
|
||||
hsci8410 NET1 enc8410 encb040
|
||||
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
.nf
|
||||
ip(8), bridge(8)
|
||||
.fi
|
||||
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Written by Alexandra Winter <wintera@linux.ibm.com>
|
||||
Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
.fi
|
||||
|
||||
@@ -21,7 +21,7 @@ clean: clean-recursive
|
||||
$(RECURSIVE_TARGETS):
|
||||
@target=`echo $@ |sed s/-recursive//`; \
|
||||
for d in $(SUBDIRS); do \
|
||||
(cd $$d && $(MAKE) $$target) \
|
||||
(cd $$d && $(MAKE) $$target) || exit 1; \
|
||||
done
|
||||
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ install-libekmfweb.so.$(VERSION): libekmfweb.so.$(VERSION)
|
||||
ln -srf $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so.$(VERM)
|
||||
ln -srf $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
|
||||
install: all $(INSTALL_TARGETS)
|
||||
|
||||
|
||||
@@ -460,7 +460,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
|
||||
rc = scan_mnt_entry(&file, entry);
|
||||
if (rc)
|
||||
goto out_free;
|
||||
if (!strcmp(entry->spec, spec)) {
|
||||
if (!strcmp(entry->vfstype, spec)) {
|
||||
rc = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
@@ -2,15 +2,27 @@
|
||||
|
||||
include ../common.mak
|
||||
|
||||
SCRIPTS = mk-s390image mk-pxelinux-ramfs
|
||||
NETBOOT_SAMPLEDIR=$(TOOLS_DATADIR)/netboot
|
||||
|
||||
all:
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
$(INSTALL) -m 755 mk-s390image mk-pxelinux-ramfs \
|
||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
$(INSTALL) -m 644 Dockerfile Makefile.pxelinux.0 README.md \
|
||||
install: install-scripts
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 \
|
||||
Dockerfile Makefile.pxelinux.0 README.md mk-s390image.1 \
|
||||
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
|
||||
|
||||
.PHONY: all install clean
|
||||
install-scripts: $(SCRIPTS)
|
||||
@if [ ! -d $(DESTDIR)$(NETBOOT_SAMPLEDIR) ]; then \
|
||||
mkdir -p $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
|
||||
fi; \
|
||||
for i in $^; do \
|
||||
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
|
||||
< $$i >$(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
|
||||
done
|
||||
|
||||
.PHONY: all install clean install-scripts
|
||||
|
||||
@@ -54,9 +54,18 @@ OPTIONS
|
||||
-b Search installed busybox in directory BUSYBOX_DIR
|
||||
-k Use KERNEL_VERSION instead of currently running kernel
|
||||
-h Print this help, then exit
|
||||
-v Print version information, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
printversion()
|
||||
{
|
||||
cat <<-EOD
|
||||
$cmd: version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2017
|
||||
EOD
|
||||
}
|
||||
|
||||
# Get shared objects for binary
|
||||
sharedobjs()
|
||||
{
|
||||
@@ -64,7 +73,7 @@ sharedobjs()
|
||||
}
|
||||
|
||||
# Check args
|
||||
args=$(getopt b:k:h $*)
|
||||
args=$(getopt b:k:hv $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
set -- $args
|
||||
@@ -74,6 +83,7 @@ then
|
||||
-b) busyboxdir=$2; shift 2;;
|
||||
-k) kernelversion=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
-v) printversion; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
esac
|
||||
|
||||
@@ -60,9 +60,18 @@ OPTIONS
|
||||
-p Use PARMFILE with kernel parameters in the image
|
||||
-r Include RAMDISK in the image
|
||||
-h Print this help, then exit
|
||||
-v Print version information, then exit
|
||||
EOF
|
||||
}
|
||||
|
||||
printversion()
|
||||
{
|
||||
cat <<-EOD
|
||||
$cmd: version %S390_TOOLS_VERSION%
|
||||
Copyright IBM Corp. 2017
|
||||
EOD
|
||||
}
|
||||
|
||||
# Convert decimal number to big endian doubleword
|
||||
dec2be64()
|
||||
{
|
||||
@@ -129,6 +138,9 @@ dobuild()
|
||||
parmfile_size=$(du -b $parmfile | cut -f1)
|
||||
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
|
||||
then
|
||||
# Clear any previous parameters
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count=$MAX_PARMFILE_SIZE \
|
||||
if=/dev/zero of=$image conv=notrunc status=none
|
||||
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
|
||||
of=$image conv=notrunc status=none
|
||||
else
|
||||
@@ -142,7 +154,7 @@ dobuild()
|
||||
}
|
||||
|
||||
# check args and build
|
||||
args=$(getopt "r:p:h" $*)
|
||||
args=$(getopt "r:p:hv" $*)
|
||||
if [ $? = 0 ]
|
||||
then
|
||||
set -- $args
|
||||
@@ -152,6 +164,7 @@ then
|
||||
-r) ramdisk=$2; shift 2;;
|
||||
-p) parmfile=$2; shift 2;;
|
||||
-h) usage; exit 0;;
|
||||
-v) printversion; exit 0;;
|
||||
--) shift; break;;
|
||||
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
|
||||
esac
|
||||
|
||||
17
netboot/mk-s390image.1
Normal file
17
netboot/mk-s390image.1
Normal file
@@ -0,0 +1,17 @@
|
||||
.TH MK-S390IMAGE "1" "November 2020" "s390-tools" "User Commands"
|
||||
.SH NAME
|
||||
mk-s390image \- tool for creating bootable image
|
||||
.SH SYNOPSIS
|
||||
.B mk-s390image
|
||||
\fI\,KERNEL BOOT_IMAGE \/\fR[\fI\,-r RAMDISK\/\fR] [\fI\,-p PARMFILE\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
|
||||
KVM firmware image using a stripped Linux kernel file KERNEL.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-p\fR Use PARMFILE with kernel parameters in the image
|
||||
.TP
|
||||
\fB\-r\fR Include RAMDISK in the image
|
||||
.TP
|
||||
\fB\-h\fR Print usage message, then exit
|
||||
@@ -10,10 +10,11 @@ zipl-switch-to-blscfg \- Switch zipl to use BootLoaderSpec configuration
|
||||
\fBzipl-switch-to-blscfg\fP {\-h|\-v}
|
||||
|
||||
.SH DESCRIPTION
|
||||
This script switches the zipl boot-loader configuration to use BootLoaderSpec files
|
||||
to define IPL sections. For each Linux kernel defined in the zipl.conf config file,
|
||||
a BLS fragment is generated in the BLS directory specified. Also, the zipl.conf is
|
||||
modified it only contains global configurations, all IPL sections comes from BLS.
|
||||
This script switches the zipl boot-loader configuration to use BootLoaderSpec
|
||||
files to define IPL sections. For each Linux kernel defined in the zipl.conf
|
||||
config file, a BLS fragment is generated in the BLS directory specified. Also,
|
||||
zipl.conf is modified to only contain global configuration. All IPL sections
|
||||
come from BLS files.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
@@ -30,7 +31,8 @@ The suffix used for backup files, defaults to .bak.
|
||||
|
||||
.TP
|
||||
\fB\-\-bls-directory <DIRECTORY>\fP
|
||||
The DIRECTORY where the BLS fragments will be generated. The directory is created if it doesn't exists, by default /boot/loader/entries is used.
|
||||
The DIRECTORY where the BLS fragments will be stored. The directory is
|
||||
created if it does not exist. By default /boot/loader/entries is used.
|
||||
|
||||
.TP
|
||||
\fB\-\-config-file <FILE>\fP
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
Description=Apply Control Program Identification (CPI)
|
||||
DefaultDependencies=no
|
||||
Conflicts=shutdown.target
|
||||
After=local-fs.target
|
||||
After=sysinit.target
|
||||
ConditionPathIsReadWrite=/sys/firmware/cpi
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
#
|
||||
# Specify a file with the environment variables using the EnvironmentFile=
|
||||
# service property.
|
||||
|
||||
@@ -387,6 +387,7 @@ function extended()
|
||||
read EXTSZ 2> /dev/null < $DEVPATH/extent_pool/extent_size
|
||||
read CAPACITY 2> /dev/null < $DEVPATH/capacity/logical_capacity
|
||||
read ALLOCATED 2> /dev/null < $DEVPATH/capacity/space_allocated
|
||||
read FC_SEC 2> /dev/null < $DEVPATH/fc_security
|
||||
|
||||
# convert to hexadecimal values
|
||||
PIM=0x$PIM
|
||||
@@ -521,7 +522,7 @@ function extended()
|
||||
elif [[ "$ALIAS" == 1 ]]; then
|
||||
if [[ "$BASEONLY" == "false" ]]; then
|
||||
ACTIVE="alias"
|
||||
printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
||||
printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
||||
"$SORTKEYLEN" "$SORTKEY" \
|
||||
"$BUSID" \
|
||||
"$ACTIVE" \
|
||||
@@ -532,6 +533,7 @@ function extended()
|
||||
"$ERP" \
|
||||
"$HPF" \
|
||||
"$DEV_UID" \
|
||||
"$FC_SEC" \
|
||||
"${INSTALLED_PATHS[@]}" \
|
||||
"${USED_PATHS[@]}" \
|
||||
"${NP_PATHS[@]}" \
|
||||
@@ -563,7 +565,7 @@ function extended()
|
||||
DISCIPLINE="${DISCIPLINE} (ESE)"
|
||||
fi
|
||||
|
||||
printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
||||
printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
|
||||
"$SORTKEYLEN" "$SORTKEY" \
|
||||
"$BUSID" \
|
||||
"$BLOCKNAME" \
|
||||
@@ -584,6 +586,7 @@ function extended()
|
||||
"$ERP" \
|
||||
"$HPF" \
|
||||
"$DEV_UID" \
|
||||
"$FC_SEC" \
|
||||
"${INSTALLED_PATHS[@]}" \
|
||||
"${USED_PATHS[@]}" \
|
||||
"${NP_PATHS[@]}" \
|
||||
|
||||
@@ -1178,8 +1178,14 @@ static int get_apqn_measurement_data(uint8_t card)
|
||||
scdmd_area.request.header.code = 0x102d;
|
||||
scdmd_area.request.header.length =
|
||||
sizeof(struct chsc_scdmd_request);
|
||||
scdmd_area.request.first_drid.ap_index = card;
|
||||
scdmd_area.request.first_drid.domain_index = g.min_domain;
|
||||
if (scdmd_area.response.p) {
|
||||
scdmd_area.request.first_drid =
|
||||
scdmd_area.response.crid;
|
||||
} else {
|
||||
scdmd_area.request.first_drid.ap_index = card;
|
||||
scdmd_area.request.first_drid.domain_index =
|
||||
g.min_domain;
|
||||
}
|
||||
scdmd_area.request.last_drid.ap_index = card;
|
||||
scdmd_area.request.last_drid.domain_index = g.max_domain;
|
||||
scdmd_area.request.s = 1;
|
||||
@@ -1217,10 +1223,6 @@ static int get_apqn_measurement_data(uint8_t card)
|
||||
rc = process_apqn_measurement_data(&scdmd_area);
|
||||
if (rc != 0)
|
||||
break;
|
||||
|
||||
if (scdmd_area.response.p)
|
||||
scdmd_area.request.first_drid =
|
||||
scdmd_area.response.crid;
|
||||
} while (scdmd_area.response.p);
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -313,6 +313,22 @@ static struct attrib dasd_attr_safe_offline = {
|
||||
.writeonly = 1,
|
||||
};
|
||||
|
||||
static struct attrib dasd_attr_fc_security = {
|
||||
.name = "fc_security",
|
||||
.title = "Show FC Endpoint Security state of DASD device",
|
||||
.desc =
|
||||
"This read-only attribute shows the Fibre Channel Endpoint Security\n"
|
||||
"status of the connection to the DASD device:\n"
|
||||
" Unsupported : The DASD device does not support Fibre Channel\n"
|
||||
" Endpoint Security\n"
|
||||
" Inconsistent : The operational channel paths of the DASD device\n"
|
||||
" report inconsistent Fibre Channel Endpoint\n"
|
||||
" Security status\n"
|
||||
" Authentication: The connection has been authenticated\n"
|
||||
" Encryption : The connection is encrypted\n",
|
||||
.readonly = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* DASD subtype methods.
|
||||
*/
|
||||
@@ -617,6 +633,7 @@ struct subtype dasd_subtype_eckd = {
|
||||
&dasd_attr_reservation_policy,
|
||||
&dasd_attr_last_known_reservation_state,
|
||||
&dasd_attr_safe_offline,
|
||||
&dasd_attr_fc_security,
|
||||
&internal_attr_early,
|
||||
),
|
||||
.unknown_dev_attribs = 1,
|
||||
|
||||
@@ -7,8 +7,6 @@ all: zkey-ekmfweb.so
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
export LIBRARY_PATH = $(rootdir)/libekmfweb:$LIBRARY_PATH
|
||||
|
||||
zkey-ekmfweb.o: zkey-ekmfweb.c zkey-ekmfweb.h ../kms-plugin.h \
|
||||
../cca.h ../utils.h ../pkey.h ../properties.h \
|
||||
$(rootdir)include/ekmfweb/ekmfweb.h libekmfweb.dep
|
||||
@@ -29,7 +27,7 @@ utils.o: ../utils.c ../utils.h ../pkey.h ../cca.h ../ep11.h
|
||||
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
zkey-ekmfweb.so: ALL_CFLAGS += -fPIC
|
||||
zkey-ekmfweb.so: LDLIBS = -lekmfweb -ldl -lcrypto
|
||||
zkey-ekmfweb.so: LDLIBS = -L$(rootdir)/libekmfweb -lekmfweb -ldl -lcrypto
|
||||
zkey-ekmfweb.so: ALL_LDFLAGS += -shared -Wl,--version-script=zkey-ekmfweb.map \
|
||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,zkey-ekmfweb.so.$(VERM)
|
||||
zkey-ekmfweb.so: zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o $(libs)
|
||||
|
||||
@@ -899,24 +899,24 @@ int kms_display_info(const kms_handle_t handle)
|
||||
if (rc == 0) {
|
||||
switch (type) {
|
||||
case EVP_PKEY_EC:
|
||||
printf(" EBMF Web public key: ECC (%s)\n",
|
||||
printf(" EKMF Web public key: ECC (%s)\n",
|
||||
OBJ_nid2sn(curve));
|
||||
break;
|
||||
case EVP_PKEY_RSA:
|
||||
printf(" EBMF Web public key: RSA "
|
||||
printf(" EKMF Web public key: RSA "
|
||||
"(%d bits)\n", mod_bits);
|
||||
break;
|
||||
default:
|
||||
printf(" EBMF Web public key: "
|
||||
printf(" EKMF Web public key: "
|
||||
"(unknown key type)\n");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
printf(" EBMF Web public key: (not available)\n");
|
||||
printf(" EKMF Web public key: (not available)\n");
|
||||
}
|
||||
free(tmp);
|
||||
} else {
|
||||
printf(" EBMF Web public key: (configuration required)\n");
|
||||
printf(" EKMF Web public key: (configuration required)\n");
|
||||
}
|
||||
|
||||
printf(" Key templates:\n");
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
#define KMS_CONFIG_PROP_KMS "kms"
|
||||
#define KMS_CONFIG_PROP_KMS_CONFIG "config"
|
||||
#define KMS_CONFIG_PROP_APQNS "apqns"
|
||||
#define KMS_CONFIG_PROP_CCA_APQNS "ep11_apqns"
|
||||
#define KMS_CONFIG_PROP_EP11_APQNS "cca_apqns"
|
||||
#define KMS_CONFIG_PROP_CCA_APQNS "cca_apqns"
|
||||
#define KMS_CONFIG_PROP_EP11_APQNS "ep11_apqns"
|
||||
#define KMS_CONFIG_LOCAL "local"
|
||||
|
||||
#define KMS_KEY_PROP_NAME "zkey-name"
|
||||
|
||||
Reference in New Issue
Block a user