The defaults provided by gnutls_set_default_priority are not configurable
at runtime. Introduce a new config option to libvirt.conf that will
be passed to gnutls_priority_set.
One of the possible options is "@SYSTEM", where gnutls will get the settings
from /etc/gnutls/default-priorities.
Note that the /etc/libvirt/libvirt.conf file is only used by libvirt
processes running as root, for regular users the file in
$XDG_CONFIG_HOME or ~/.config is used.
https://bugzilla.redhat.com/show_bug.cgi?id=1333404
---
src/libvirt.conf | 6 +++++
src/rpc/virnettlscontext.c | 59 +++++++++++++++++++++++++++++++++++++++-------
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/src/libvirt.conf b/src/libvirt.conf
index da4dfbe..688c572 100644
--- a/src/libvirt.conf
+++ b/src/libvirt.conf
@@ -16,3 +16,9 @@
# (@uri_default also prevents probing of the hypervisor driver).
#
#uri_default = "qemu:///system"
+
+#
+# Override the priority of exchange methods, ciphers etc. used by gnutls.
+# See gnutls_priority_set_direct(3).
+#
+#gnutls_priority = "@SYSTEM"
diff --git a/src/rpc/virnettlscontext.c b/src/rpc/virnettlscontext.c
index 947038d..e93887c 100644
--- a/src/rpc/virnettlscontext.c
+++ b/src/rpc/virnettlscontext.c
@@ -35,6 +35,7 @@
#include "virstring.h"
#include "viralloc.h"
+#include "virconf.h"
#include "virerror.h"
#include "virfile.h"
#include "virutil.h"
@@ -86,10 +87,17 @@ static virClassPtr virNetTLSContextClass;
static virClassPtr virNetTLSSessionClass;
static void virNetTLSContextDispose(void *obj);
static void virNetTLSSessionDispose(void *obj);
+static gnutls_priority_t *virNetTLSPriorityCache;
static int virNetTLSContextOnceInit(void)
{
+ virConfPtr conf = NULL;
+ virConfValuePtr value = NULL;
+ const char *err_pos;
+ int ret = -1;
+ int rc;
+
if (!(virNetTLSContextClass = virClassNew(virClassForObjectLockable(),
"virNetTLSContext",
sizeof(virNetTLSContext),
@@ -102,7 +110,32 @@ static int virNetTLSContextOnceInit(void)
virNetTLSSessionDispose)))
return -1;
- return 0;
+ if (virConfLoadConfig(&conf, NULL) < 0)
+ return -1;
+
+ if ((value = virConfGetValue(conf, "gnutls_priority"))) {
+ if (value->type != VIR_CONF_STRING) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expected a string for 'gnutls_priority' config
parameter"));
+ goto cleanup;
+ }
+ VIR_DEBUG("Using gnutls priority '%s'", value->str);
+ if (VIR_ALLOC(virNetTLSPriorityCache) < 0)
+ goto cleanup;
+ if ((rc = gnutls_priority_init(virNetTLSPriorityCache, value->str,
+ &err_pos)) != 0) {
+ VIR_FREE(virNetTLSPriorityCache);
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Failed to initialize TLS session priority
\"%s\": %s"),
+ err_pos, gnutls_strerror(rc));
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+ cleanup:
+ virConfFree(conf);
+ return ret;
}
VIR_ONCE_GLOBAL_INIT(virNetTLSContext)
@@ -1224,14 +1257,22 @@ virNetTLSSessionPtr virNetTLSSessionNew(virNetTLSContextPtr ctxt,
goto error;
}
- /* avoid calling all the priority functions, since the defaults
- * are adequate.
- */
- if ((err = gnutls_set_default_priority(sess->session)) != 0) {
- virReportError(VIR_ERR_SYSTEM_ERROR,
- _("Failed to set TLS session priority %s"),
- gnutls_strerror(err));
- goto error;
+ /* Use the defaults unless a priority string was specified in the
+ * config file */
+ if (virNetTLSPriorityCache) {
+ if ((err = gnutls_priority_set(sess->session, *virNetTLSPriorityCache)) != 0)
{
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Failed to set TLS session priority %s"),
+ gnutls_strerror(err));
+ goto error;
+ }
+ } else {
+ if ((err = gnutls_set_default_priority(sess->session)) != 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("Failed to set TLS session priority %s"),
+ gnutls_strerror(err));
+ goto error;
+ }
}
if ((err = gnutls_credentials_set(sess->session,
--
2.7.3