[libvirt] [PATCH] Introduce gnutls_priority config option

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

On Wed, May 18, 2016 at 01:54:47PM +0200, Ján Tomko wrote:
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.
NACK, per that bug this is supposed to be configurable systemwide for gnutls. We need to investigate why Jaroslav could not get that to work, since we don't want to be adding custom application specific TLS config for every part of the virt stack that uses TLS (libvirt, gtk-vnc, spice-gtk, spice, qemu, etc). Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Thu, May 19, 2016 at 10:36:26AM +0100, Daniel P. Berrange wrote:
On Wed, May 18, 2016 at 01:54:47PM +0200, Ján Tomko wrote:
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.
NACK, per that bug this is supposed to be configurable systemwide for gnutls. We need to investigate why Jaroslav could not get that to work, since we don't want to be adding custom application specific TLS config for every part of the virt stack that uses TLS (libvirt, gtk-vnc, spice-gtk, spice, qemu, etc).
I could not get it to work either. Using "NORMAL" either directly or via gnutls_set_default_priority, the default-settings file is ignored. Skimming through gnutls code, I assumed this was intentional. Jan

On Thu, May 19, 2016 at 01:47:02PM +0200, Ján Tomko wrote:
On Thu, May 19, 2016 at 10:36:26AM +0100, Daniel P. Berrange wrote:
On Wed, May 18, 2016 at 01:54:47PM +0200, Ján Tomko wrote:
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.
NACK, per that bug this is supposed to be configurable systemwide for gnutls. We need to investigate why Jaroslav could not get that to work, since we don't want to be adding custom application specific TLS config for every part of the virt stack that uses TLS (libvirt, gtk-vnc, spice-gtk, spice, qemu, etc).
I could not get it to work either. Using "NORMAL" either directly or via gnutls_set_default_priority, the default-settings file is ignored.
Skimming through gnutls code, I assumed this was intentional.
I've just verified on current Fedora I can edit /etc/crypto-policies/config and set 'LEGACY' 'DEFAULT' or 'FUTURE', run 'update-crypto-policies' and restart libvirtd and it honours the newly chosen cipher/protocol defaults from gnutls. So at least on Fedora gnutls is working as designed. If RHEL gnutls doesn't provide a way to change global defaults, then I really think effort is better spent fixing this in gnutls rather than changing code in libvirt, qemu, gtk-vnc, spice-gtk and many other places to add app specific config files todo the same thing. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Daniel P. Berrange
-
Ján Tomko