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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list