Add an API to update server's tls context. --- src/libvirt_remote.syms | 1 + src/rpc/virnetserver.c | 51 ++++++++++++++++++++++++++++++++++++++ src/rpc/virnetserver.h | 2 ++ src/rpc/virnettlscontext.c | 46 ++++++++++++++++++++++++++++++++++ src/rpc/virnettlscontext.h | 3 +++ 5 files changed, 103 insertions(+) diff --git a/src/libvirt_remote.syms b/src/libvirt_remote.syms index 0493467f46..0018a0c41d 100644 --- a/src/libvirt_remote.syms +++ b/src/libvirt_remote.syms @@ -137,6 +137,7 @@ virNetServerSetClientLimits; virNetServerSetThreadPoolParameters; virNetServerSetTLSContext; virNetServerUpdateServices; +virNetServerUpdateTlsFiles; # rpc/virnetserverclient.h diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 072ffdf5a3..0bfe94d3f8 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -21,6 +21,9 @@ #include <config.h> +#include <sys/types.h> +#include <unistd.h> + #include "virnetserver.h" #include "virlog.h" #include "viralloc.h" @@ -1205,3 +1208,51 @@ virNetServerSetClientLimits(virNetServerPtr srv, virObjectUnlock(srv); return ret; } + +static virNetTLSContextPtr +virNetServerGetTLSContext(virNetServerPtr srv) +{ + size_t i; + virNetTLSContextPtr ctxt = NULL; + virNetServerServicePtr svc = NULL; + + /* find svcTLS from srv, get svcTLS->tls */ + for (i = 0; i < srv->nservices; i++) { + svc = srv->services[i]; + ctxt = virNetServerServiceGetTLSContext(svc); + if (ctxt != NULL) + break; + } + + return ctxt; +} + +int +virNetServerUpdateTlsFiles(virNetServerPtr srv) +{ + int ret = -1; + virNetTLSContextPtr ctxt = NULL; + bool privileged = geteuid() == 0 ? true : false; + + ctxt = virNetServerGetTLSContext(srv); + if (!ctxt) { + VIR_ERROR(_("no tls svc found, unable to update tls files")); + return -1; + } + + virObjectLock(srv); + virObjectLock(ctxt); + + if (virNetTLSContextReloadForServer(ctxt, !privileged)) { + VIR_ERROR(_("failed to reload server's tls context")); + goto cleanup; + } + + VIR_INFO("update tls files success"); + ret = 0; + + cleanup: + virObjectUnlock(ctxt); + virObjectUnlock(srv); + return ret; +} diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index 260c99b22d..1c6a2efb6c 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -133,3 +133,5 @@ size_t virNetServerGetCurrentUnauthClients(virNetServerPtr srv); int virNetServerSetClientLimits(virNetServerPtr srv, long long int maxClients, long long int maxClientsUnauth); + +int virNetServerUpdateTlsFiles(virNetServerPtr srv); diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c index 44f0dfce77..02c17124a1 100644 --- a/src/rpc/virnettlscontext.c +++ b/src/rpc/virnettlscontext.c @@ -919,6 +919,52 @@ virNetTLSContextPtr virNetTLSContextNewServer(const char *cacert, } +int virNetTLSContextReloadForServer(virNetTLSContextPtr ctxt, + bool tryUserPkiPath) +{ + gnutls_certificate_credentials_t x509credBak; + int err; + char *cacert = NULL; + char *cacrl = NULL; + char *cert = NULL; + char *key = NULL; + + x509credBak = ctxt->x509cred; + ctxt->x509cred = NULL; + + if (virNetTLSContextLocateCredentials(NULL, tryUserPkiPath, true, + &cacert, &cacrl, &cert, &key)) + goto error; + + err = gnutls_certificate_allocate_credentials(&ctxt->x509cred); + if (err) { + virReportError(VIR_ERR_SYSTEM_ERROR, + _("Unable to allocate x509 credentials: %s"), + gnutls_strerror(err)); + goto error; + } + + if (virNetTLSContextSanityCheckCredentials(true, cacert, cert)) + goto error; + + if (virNetTLSContextLoadCredentials(ctxt, true, cacert, cacrl, cert, key)) + goto error; + + gnutls_certificate_set_dh_params(ctxt->x509cred, + ctxt->dhParams); + + gnutls_certificate_free_credentials(x509credBak); + + return 0; + + error: + if (ctxt->x509cred) + gnutls_certificate_free_credentials(ctxt->x509cred); + ctxt->x509cred = x509credBak; + return -1; +} + + virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert, const char *cacrl, const char *cert, diff --git a/src/rpc/virnettlscontext.h b/src/rpc/virnettlscontext.h index f3273bc26a..fe885aed9a 100644 --- a/src/rpc/virnettlscontext.h +++ b/src/rpc/virnettlscontext.h @@ -62,6 +62,9 @@ virNetTLSContextPtr virNetTLSContextNewClient(const char *cacert, bool sanityCheckCert, bool requireValidCert); +int virNetTLSContextReloadForServer(virNetTLSContextPtr ctxt, + bool tryUserPkiPath); + int virNetTLSContextCheckCertificate(virNetTLSContextPtr ctxt, virNetTLSSessionPtr sess); -- 2.23.0.windows.1