[PATCH 2/6] tools: Add virt-pki-query-dn binary
Daniel P. Berrangé
berrange at redhat.com
Thu Nov 11 15:38:24 UTC 2021
On Thu, Nov 11, 2021 at 04:06:42PM +0100, Martin Kletzander wrote:
> With this program we do not have to depend on the output of `certtool -i`, which
> changed the order of the fields at some point and the newest version is
> incompatible with what libvirt expects in tls_allowed_dn_list configuration
> option.
>
> Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
> ---
> libvirt.spec.in | 1 +
> po/POTFILES.in | 1 +
> tools/meson.build | 26 ++++++++
> tools/virt-pki-query-dn.c | 137 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 165 insertions(+)
> create mode 100644 tools/virt-pki-query-dn.c
>
> diff --git a/libvirt.spec.in b/libvirt.spec.in
> index 4ecb28114ce8..5f1773ef93f2 100644
> --- a/libvirt.spec.in
> +++ b/libvirt.spec.in
> @@ -1983,6 +1983,7 @@ exit 0
> %{_mandir}/man1/virt-pki-validate.1*
> %{_bindir}/virsh
> %{_bindir}/virt-xml-validate
> +%{_bindir}/virt-pki-query-dn
> %{_bindir}/virt-pki-validate
>
> %{_datadir}/bash-completion/completions/virsh
> diff --git a/po/POTFILES.in b/po/POTFILES.in
> index 8a726f624e38..bf0a3b352979 100644
> --- a/po/POTFILES.in
> +++ b/po/POTFILES.in
> @@ -376,6 +376,7 @@
> @SRCDIR at tools/virt-host-validate-qemu.c
> @SRCDIR at tools/virt-host-validate.c
> @SRCDIR at tools/virt-login-shell-helper.c
> + at SRCDIR@tools/virt-pki-query-dn.c
> @SRCDIR at tools/vsh-table.c
> @SRCDIR at tools/vsh.c
> @SRCDIR at tools/vsh.h
> diff --git a/tools/meson.build b/tools/meson.build
> index bf0eab8b6bf2..9fc07ef32bb3 100644
> --- a/tools/meson.build
> +++ b/tools/meson.build
> @@ -257,6 +257,32 @@ configure_file(
> install_mode: 'rwxrwxr-x',
> )
>
> +executable(
> + 'virt-pki-query-dn',
> + [
> + 'virt-pki-query-dn.c',
> + ],
> + dependencies: [
> + glib_dep,
> + gnutls_dep,
> + ],
> + include_directories: [
> + src_inc_dir,
> + top_inc_dir,
> + util_inc_dir,
> + ],
> + link_args: (
> + libvirt_relro
> + + libvirt_no_indirect
> + + libvirt_no_undefined
> + ),
> + link_with: [
> + libvirt_lib
> + ],
> + install: true,
> + install_dir: bindir,
> +)
> +
> if conf.has('WITH_SANLOCK')
> configure_file(
> input: 'virt-sanlock-cleanup.in',
> diff --git a/tools/virt-pki-query-dn.c b/tools/virt-pki-query-dn.c
> new file mode 100644
> index 000000000000..0706256d0016
> --- /dev/null
> +++ b/tools/virt-pki-query-dn.c
> @@ -0,0 +1,137 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include <config.h>
> +#include "internal.h"
> +
> +#include <err.h>
This is not a standard C library API. Doesn't exist on Mingw at least
AFAICT.
> +#include <getopt.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#include <gnutls/gnutls.h>
> +#include <gnutls/x509.h>
> +
> +#include "virgettext.h"
> +
> +
> +static void
> +glib_auto_cleanup_gnutls_x509_crt_t(gnutls_x509_crt_t *pointer)
> +{
> + gnutls_x509_crt_deinit(*pointer);
> +}
> +
> +
> +static void
> +print_usage(const char *progname,
> + FILE *out)
> +{
> + fprintf(out,
> + _("Usage:\n"
> + " %s FILE\n"
> + " %s { -v | -h }\n"
> + "\n"
> + "Extract Distinguished Name from a PEM certificate.\n"
> + "The output is meant to be used in the tls_allowed_dn_list\n"
> + "configuration option in the libvirtd.conf file.\n"
> + "\n"
> + " FILE certificate file to extract the DN from\n"
> + "\n"
> + "options:\n"
> + " -h | --help display this help and exit\n"
> + " -v | --version output version information and exit\n"),
> + progname, progname);
> +}
> +
> +
> +int
> +main(int argc,
> + char **argv)
> +{
> + const char *progname = NULL;
> + const char *filename = NULL;
> + size_t dnamesize = 256;
> + size_t bufsize = 0;
> + g_autofree char *dname = g_new0(char, dnamesize);
> + g_autofree char *buf = NULL;
> + g_auto(gnutls_x509_crt_t) crt = {0};
> + gnutls_datum_t crt_data = {0};
> + g_autoptr(GError) error = NULL;
> + int arg = 0;
> + int rv = 0;
> +
> + struct option opt[] = {
> + {"help", no_argument, NULL, 'h'},
> + {"version", optional_argument, NULL, 'v'},
> + {NULL, 0, NULL, 0}
> + };
> +
> + if (virGettextInitialize() < 0)
> + return EXIT_FAILURE;
> +
> + if (!(progname = strrchr(argv[0], '/')))
> + progname = argv[0];
> + else
> + progname++;
> +
> + while ((arg = getopt_long(argc, argv, "hv", opt, NULL)) != -1) {
> + switch (arg) {
> + case 'v':
> + printf("%s\n", PACKAGE_VERSION);
> + return EXIT_SUCCESS;
> + case 'h':
> + print_usage(progname, stdout);
> + return EXIT_SUCCESS;
> + default:
> + print_usage(progname, stderr);
> + return EXIT_FAILURE;
> + }
> + }
> +
> + if (optind != argc - 1) {
> + print_usage(progname, stderr);
> + return EXIT_FAILURE;
> + }
> +
> + filename = argv[optind];
> +
> + g_file_get_contents(filename, &buf, &bufsize, &error);
> + if (error)
> + errx(EXIT_FAILURE, "%s", error->message);
IMHO better to just use g_printerr() and return EXIT_FAILURE
so the control flow isn't disguised, and the API is portable.
> +
> + if (bufsize > UINT_MAX)
> + errx(EXIT_FAILURE, _("File '%s' is too large"), filename);
> +
> + crt_data.data = (unsigned char *)buf;
> + crt_data.size = bufsize;
> +
> + rv = gnutls_x509_crt_init(&crt);
> + if (rv < 0) {
> + err(EXIT_FAILURE,
> + _("Unable to initialize certificate: %s"),
> + gnutls_strerror(rv));
> + }
> +
> + rv = gnutls_x509_crt_import(crt, &crt_data, GNUTLS_X509_FMT_PEM);
> + if (rv < 0) {
> + err(EXIT_FAILURE,
> + _("Unable to load certificate, make sure it is in PEM format: %s"),
> + gnutls_strerror(rv));
> + }
> +
> + rv = gnutls_x509_crt_get_dn(crt, dname, &dnamesize);
> + if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER) {
> + dname = g_realloc(dname, dnamesize);
> + rv = gnutls_x509_crt_get_dn(crt, dname, &dnamesize);
> + }
> + if (rv != 0) {
> + err(EXIT_FAILURE,
> + _("Failed to get distinguished name: %s"),
> + gnutls_strerror(rv));
> + }
> +
> + printf("%s\n", dname);
> +
> + return EXIT_SUCCESS;
> +}
> --
> 2.33.1
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list