[PATCH 1/9] rpc: split out helpers for TLS cert path location

Daniel P. Berrangé posted 9 patches 3 months, 1 week ago
[PATCH 1/9] rpc: split out helpers for TLS cert path location
Posted by Daniel P. Berrangé 3 months, 1 week ago
We'll want to access these paths from outside the TLS context code,
so split them into a standalone file.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
 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..d11d532d0f 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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#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
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#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 <gnutls/x509.h>
 
 #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;
 }
-- 
2.43.0
Re: [PATCH 1/9] rpc: split out helpers for TLS cert path location
Posted by Michal Prívozník 3 months, 1 week ago
On 6/7/24 16:26, Daniel P. Berrangé wrote:
> We'll want to access these paths from outside the TLS context code,
> so split them into a standalone file.
> 
> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> ---
>  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..d11d532d0f 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'),
> +]

I believe this should be either:

  tlsconfig_sources = [ ... ]

or

  tlsconfig_sources = files( ... )

and given that the latter remembers the subdir of passed files then I'd
just stick to it.

Michal
Re: [PATCH 1/9] rpc: split out helpers for TLS cert path location
Posted by Daniel P. Berrangé 3 months, 1 week ago
On Mon, Jun 10, 2024 at 01:57:21PM +0200, Michal Prívozník wrote:
> On 6/7/24 16:26, Daniel P. Berrangé wrote:
> > We'll want to access these paths from outside the TLS context code,
> > so split them into a standalone file.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
> > ---
> >  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..d11d532d0f 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'),
> > +]
> 
> I believe this should be either:
> 
>   tlsconfig_sources = [ ... ]

This doesn't work as we need the sub-dir remembered, so that a later
patch in the series can reference this from the tools/ subdir.

> or
> 
>   tlsconfig_sources = files( ... )
> 
> and given that the latter remembers the subdir of passed files then I'd
> just stick to it.

With 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 :|