From e66c3bcd0cf663ead453d9abfd69e119b6700002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Thu, 6 Jun 2024 15:13:44 +0100 Subject: [PATCH] rpc: split out helpers for TLS cert path location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We'll want to access these paths from outside the TLS context code, so split them into a standalone file. Reviewed-by: Michal Privoznik Signed-off-by: Daniel P. Berrangé --- src/rpc/meson.build | 6 +- src/rpc/virnettlsconfig.c | 202 +++++++++++++++++++++++++++++++++++++ src/rpc/virnettlsconfig.h | 68 +++++++++++++ src/rpc/virnettlscontext.c | 70 ++----------- 4 files changed, 285 insertions(+), 61 deletions(-) create mode 100644 src/rpc/virnettlsconfig.c create mode 100644 src/rpc/virnettlsconfig.h diff --git a/src/rpc/meson.build b/src/rpc/meson.build index 9d98bc6259..e9a69bbe2f 100644 --- a/src/rpc/meson.build +++ b/src/rpc/meson.build @@ -1,6 +1,10 @@ gendispatch_prog = find_program('gendispatch.pl') -socket_sources = [ +tlsconfig_sources = files( + 'virnettlsconfig.c', +) + +socket_sources = tlsconfig_sources + [ 'virnettlscontext.c', 'virnetsocket.c', ] diff --git a/src/rpc/virnettlsconfig.c b/src/rpc/virnettlsconfig.c new file mode 100644 index 0000000000..d020083d6a --- /dev/null +++ b/src/rpc/virnettlsconfig.c @@ -0,0 +1,202 @@ +/* + * virnettlsconfig.c: TLS x509 configuration helpers + * + * Copyright (C) 2010-2024 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include "virnettlsconfig.h" +#include "virlog.h" +#include "virutil.h" + +#define VIR_FROM_THIS VIR_FROM_RPC + +VIR_LOG_INIT("rpc.nettlscontext"); + +char *virNetTLSConfigUserPKIBaseDir(void) +{ + g_autofree char *userdir = virGetUserDirectory(); + + return g_strdup_printf("%s/.pki/libvirt", userdir); +} + +static void virNetTLSConfigTrust(const char *cacertdir, + const char *cacrldir, + char **cacert, + char **cacrl) +{ + if (!*cacert) + *cacert = g_strdup_printf("%s/%s", cacertdir, "cacert.pem"); + if (!*cacrl) + *cacrl = g_strdup_printf("%s/%s", cacrldir, "cacrl.pem"); + + VIR_DEBUG("TLS CA cert %s", *cacert); + VIR_DEBUG("TLS CA CRL %s", *cacrl); +} + +static void virNetTLSConfigIdentity(int isServer, + const char *certdir, + const char *keydir, + char **cert, + char **key) +{ + if (!*key) + *key = g_strdup_printf("%s/%s", keydir, + isServer ? "serverkey.pem" : "clientkey.pem"); + if (!*cert) + *cert = g_strdup_printf("%s/%s", certdir, + isServer ? "servercert.pem" : "clientcert.pem"); + + VIR_DEBUG("TLS key %s", *key); + VIR_DEBUG("TLS cert %s", *cert); +} + +void virNetTLSConfigCustomTrust(const char *pkipath, + char **cacert, + char **cacrl) +{ + VIR_DEBUG("Locating trust chain in custom dir %s", pkipath); + virNetTLSConfigTrust(pkipath, + pkipath, + cacert, + cacrl); +} + +void virNetTLSConfigUserTrust(char **cacert, + char **cacrl) +{ + g_autofree char *pkipath = virNetTLSConfigUserPKIBaseDir(); + + VIR_DEBUG("Locating trust chain in user dir %s", pkipath); + + virNetTLSConfigTrust(pkipath, + pkipath, + cacert, + cacrl); +} + +void virNetTLSConfigSystemTrust(char **cacert, + char **cacrl) +{ + VIR_DEBUG("Locating trust chain in system dir %s", LIBVIRT_PKI_DIR); + + virNetTLSConfigTrust(LIBVIRT_CACERT_DIR, + LIBVIRT_CACRL_DIR, + cacert, + cacrl); +} + +void virNetTLSConfigCustomIdentity(const char *pkipath, + int isServer, + char **cert, + char **key) +{ + VIR_DEBUG("Locating creds in custom dir %s", pkipath); + virNetTLSConfigIdentity(isServer, + pkipath, + pkipath, + cert, + key); +} + +void virNetTLSConfigUserIdentity(int isServer, + char **cert, + char **key) +{ + g_autofree char *pkipath = virNetTLSConfigUserPKIBaseDir(); + + VIR_DEBUG("Locating creds in user dir %s", pkipath); + + virNetTLSConfigIdentity(isServer, + pkipath, + pkipath, + cert, + key); +} + +void virNetTLSConfigSystemIdentity(int isServer, + char **cert, + char **key) +{ + VIR_DEBUG("Locating creds in system dir %s", LIBVIRT_PKI_DIR); + + virNetTLSConfigIdentity(isServer, + LIBVIRT_CERT_DIR, + LIBVIRT_KEY_DIR, + cert, + key); +} + +void virNetTLSConfigCustomCreds(const char *pkipath, + int isServer, + char **cacert, + char **cacrl, + char **cert, + char **key) +{ + VIR_DEBUG("Locating creds in custom dir %s", pkipath); + virNetTLSConfigTrust(pkipath, + pkipath, + cacert, + cacrl); + virNetTLSConfigIdentity(isServer, + pkipath, + pkipath, + cert, + key); +} + +void virNetTLSConfigUserCreds(int isServer, + char **cacert, + char **cacrl, + char **cert, + char **key) +{ + g_autofree char *pkipath = virNetTLSConfigUserPKIBaseDir(); + + VIR_DEBUG("Locating creds in user dir %s", pkipath); + + virNetTLSConfigTrust(pkipath, + pkipath, + cacert, + cacrl); + virNetTLSConfigIdentity(isServer, + pkipath, + pkipath, + cert, + key); +} + +void virNetTLSConfigSystemCreds(int isServer, + char **cacert, + char **cacrl, + char **cert, + char **key) +{ + VIR_DEBUG("Locating creds in system dir %s", LIBVIRT_PKI_DIR); + + virNetTLSConfigTrust(LIBVIRT_CACERT_DIR, + LIBVIRT_CACRL_DIR, + cacert, + cacrl); + virNetTLSConfigIdentity(isServer, + LIBVIRT_CERT_DIR, + LIBVIRT_KEY_DIR, + cert, + key); +} diff --git a/src/rpc/virnettlsconfig.h b/src/rpc/virnettlsconfig.h new file mode 100644 index 0000000000..797b3e3ac5 --- /dev/null +++ b/src/rpc/virnettlsconfig.h @@ -0,0 +1,68 @@ +/* + * virnettlsconfig.h: TLS x509 configuration helpers + * + * Copyright (C) 2010-2024 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#pragma once + +#include "configmake.h" + +#define LIBVIRT_PKI_DIR SYSCONFDIR "/pki" +#define LIBVIRT_CACERT_DIR LIBVIRT_PKI_DIR "/CA" +#define LIBVIRT_CACRL_DIR LIBVIRT_PKI_DIR "/CA" +#define LIBVIRT_KEY_DIR LIBVIRT_PKI_DIR "/libvirt/private" +#define LIBVIRT_CERT_DIR LIBVIRT_PKI_DIR "/libvirt" + +char *virNetTLSConfigUserPKIBaseDir(void); + +void virNetTLSConfigCustomTrust(const char *pkipath, + char **cacert, + char **cacrl); +void virNetTLSConfigUserTrust(char **cacert, + char **cacrl); +void virNetTLSConfigSystemTrust(char **cacert, + char **cacrl); + +void virNetTLSConfigCustomIdentity(const char *pkipath, + int isServer, + char **cert, + char **key); +void virNetTLSConfigUserIdentity(int isServer, + char **cert, + char **key); +void virNetTLSConfigSystemIdentity(int isServer, + char **cert, + char **key); + + +void virNetTLSConfigCustomCreds(const char *pkipath, + int isServer, + char **cacert, + char **cacrl, + char **cert, + char **key); +void virNetTLSConfigUserCreds(int isServer, + char **cacert, + char **cacrl, + char **cert, + char **key); +void virNetTLSConfigSystemCreds(int isServer, + char **cacert, + char **cacrl, + char **cert, + char **key); diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c index dc60244927..4223043bc9 100644 --- a/src/rpc/virnettlscontext.c +++ b/src/rpc/virnettlscontext.c @@ -27,6 +27,7 @@ #include #include "virnettlscontext.h" +#include "virnettlsconfig.h" #include "virstring.h" #include "viralloc.h" @@ -36,15 +37,6 @@ #include "virlog.h" #include "virprobe.h" #include "virthread.h" -#include "configmake.h" - -#define LIBVIRT_PKI_DIR SYSCONFDIR "/pki" -#define LIBVIRT_CACERT LIBVIRT_PKI_DIR "/CA/cacert.pem" -#define LIBVIRT_CACRL LIBVIRT_PKI_DIR "/CA/cacrl.pem" -#define LIBVIRT_CLIENTKEY LIBVIRT_PKI_DIR "/libvirt/private/clientkey.pem" -#define LIBVIRT_CLIENTCERT LIBVIRT_PKI_DIR "/libvirt/clientcert.pem" -#define LIBVIRT_SERVERKEY LIBVIRT_PKI_DIR "/libvirt/private/serverkey.pem" -#define LIBVIRT_SERVERCERT LIBVIRT_PKI_DIR "/libvirt/servercert.pem" #define VIR_FROM_THIS VIR_FROM_RPC @@ -721,9 +713,6 @@ static int virNetTLSContextLocateCredentials(const char *pkipath, char **cert, char **key) { - char *userdir = NULL; - char *user_pki_path = NULL; - *cacert = NULL; *cacrl = NULL; *key = NULL; @@ -736,33 +725,13 @@ static int virNetTLSContextLocateCredentials(const char *pkipath, * files actually exist there */ if (pkipath) { - VIR_DEBUG("Told to use TLS credentials in %s", pkipath); - *cacert = g_strdup_printf("%s/%s", pkipath, "cacert.pem"); - *cacrl = g_strdup_printf("%s/%s", pkipath, "cacrl.pem"); - *key = g_strdup_printf("%s/%s", pkipath, - isServer ? "serverkey.pem" : "clientkey.pem"); - - *cert = g_strdup_printf("%s/%s", pkipath, - isServer ? "servercert.pem" : "clientcert.pem"); + virNetTLSConfigCustomCreds(pkipath, isServer, + cacert, cacrl, + cert, key); } else if (tryUserPkiPath) { - /* Check to see if $HOME/.pki contains at least one of the - * files and if so, use that - */ - userdir = virGetUserDirectory(); - - user_pki_path = g_strdup_printf("%s/.pki/libvirt", userdir); - - VIR_DEBUG("Trying to find TLS user credentials in %s", user_pki_path); - - *cacert = g_strdup_printf("%s/%s", user_pki_path, "cacert.pem"); - - *cacrl = g_strdup_printf("%s/%s", user_pki_path, "cacrl.pem"); - - *key = g_strdup_printf("%s/%s", user_pki_path, - isServer ? "serverkey.pem" : "clientkey.pem"); - - *cert = g_strdup_printf("%s/%s", user_pki_path, - isServer ? "servercert.pem" : "clientcert.pem"); + virNetTLSConfigUserCreds(isServer, + cacert, cacrl, + cert, key); /* * If some of the files can't be found, fallback @@ -782,28 +751,9 @@ static int virNetTLSContextLocateCredentials(const char *pkipath, } } - /* No explicit path, or user path didn't exist, so - * fallback to global defaults - */ - if (!*cacert) { - VIR_DEBUG("Using default TLS CA certificate path"); - *cacert = g_strdup(LIBVIRT_CACERT); - } - - if (!*cacrl) { - VIR_DEBUG("Using default TLS CA revocation list path"); - *cacrl = g_strdup(LIBVIRT_CACRL); - } - - if (!*key && !*cert) { - VIR_DEBUG("Using default TLS key/certificate path"); - *key = g_strdup(isServer ? LIBVIRT_SERVERKEY : LIBVIRT_CLIENTKEY); - - *cert = g_strdup(isServer ? LIBVIRT_SERVERCERT : LIBVIRT_CLIENTCERT); - } - - VIR_FREE(user_pki_path); - VIR_FREE(userdir); + virNetTLSConfigSystemCreds(isServer, + cacert, cacrl, + cert, key); return 0; }