From b44af714d358471699deb9aaec4080b7f7a71dc2 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Mon, 16 Mar 2009 13:54:26 +0000 Subject: [PATCH] Support SASL auth for VNC server. --- ChangeLog | 16 ++++++++ qemud/libvirtd_qemu.aug | 2 + qemud/test_libvirtd_qemu.aug | 38 ++++++++++++++++++ src/qemu.conf | 21 ++++++++++ src/qemu_conf.c | 39 ++++++++++++++++--- src/qemu_conf.h | 2 + src/qemu_driver.c | 1 + .../qemuxml2argv-graphics-vnc-sasl.args | 1 + .../qemuxml2argv-graphics-vnc-sasl.xml | 24 ++++++++++++ .../qemuxml2argv-graphics-vnc-tls.args | 1 + .../qemuxml2argv-graphics-vnc-tls.xml | 24 ++++++++++++ tests/qemuxml2argvtest.c | 13 +++++++ 12 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml diff --git a/ChangeLog b/ChangeLog index 6fdfd278cc..a40fa1ba5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +Mon Mar 16 13:52:00 GMT 2009 Daniel P. Berrange + + Support SASL auth for VNC server. + * qemud/libvirtd_qemu.aug, qemud/test_libvirtd_qemu.aug: Add + support for VNC sasl config options + * src/qemu.conf: Example VNC sasl config options + * src/qemu_conf.c, src/qemu_conf.h, src/qemu_driver.c: Add + ability to set SASL authentication on VNC servers + * tests/qemuxml2argvtest.c: Test for VNC SASL and TLS security + options + * tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.args, + tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml, + tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args, + tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml: Data + files for tests + Mon Mar 16 11:44:00 GMT 2009 Daniel P. Berrange * src/qemu_driver.c: Avoid deadlock in virDomainSetVcpus diff --git a/qemud/libvirtd_qemu.aug b/qemud/libvirtd_qemu.aug index b2e4318979..02699d6362 100644 --- a/qemud/libvirtd_qemu.aug +++ b/qemud/libvirtd_qemu.aug @@ -27,6 +27,8 @@ module Libvirtd_qemu = | str_entry "vnc_tls_x509_cert_dir" | bool_entry "vnc_tls_x509_verify" | str_entry "vnc_password" + | bool_entry "vnc_sasl" + | str_entry "vnc_sasl_dir" (* Each enty in the config is one of the following three ... *) let entry = vnc_entry diff --git a/qemud/test_libvirtd_qemu.aug b/qemud/test_libvirtd_qemu.aug index 083ccbaf02..6f38e47e3b 100644 --- a/qemud/test_libvirtd_qemu.aug +++ b/qemud/test_libvirtd_qemu.aug @@ -60,6 +60,25 @@ vnc_tls_x509_verify = 1 # example here before you set this # vnc_password = \"XYZ12345\" + + +# Enable use of SASL encryption on the VNC server. This requires +# a VNC client which supports the SASL protocol extension. +# Examples include vinagre, virt-viewer and virt-manager +# itself. UltraVNC, RealVNC, TightVNC do not support this +# +# It is necessary to configure /etc/sasl2/qemu.conf to choose +# the desired SASL plugin (eg, GSSPI for Kerberos) +# +vnc_sasl = 1 + + +# The default SASL configuration file is located in /etc/sasl2/ +# When running libvirtd unprivileged, it may be desirable to +# override the configs in this location. Set this parameter to +# point to the directory, and create a qemu.conf in that location +# +vnc_sasl_dir = \"/some/directory/sasl2\" " test Libvirtd_qemu.lns get conf = @@ -123,3 +142,22 @@ vnc_password = \"XYZ12345\" { "#comment" = "example here before you set this" } { "#comment" = "" } { "vnc_password" = "XYZ12345" } +{ "#empty" } +{ "#empty" } +{ "#comment" = "Enable use of SASL encryption on the VNC server. This requires" } +{ "#comment" = "a VNC client which supports the SASL protocol extension." } +{ "#comment" = "Examples include vinagre, virt-viewer and virt-manager" } +{ "#comment" = "itself. UltraVNC, RealVNC, TightVNC do not support this" } +{ "#comment" = "" } +{ "#comment" = "It is necessary to configure /etc/sasl2/qemu.conf to choose" } +{ "#comment" = "the desired SASL plugin (eg, GSSPI for Kerberos)" } +{ "#comment" = "" } +{ "vnc_sasl" = "1" } +{ "#empty" } +{ "#empty" } +{ "#comment" = "The default SASL configuration file is located in /etc/sasl2/" } +{ "#comment" = "When running libvirtd unprivileged, it may be desirable to" } +{ "#comment" = "override the configs in this location. Set this parameter to" } +{ "#comment" = "point to the directory, and create a qemu.conf in that location" } +{ "#comment" = "" } +{ "vnc_sasl_dir" = "/some/directory/sasl2" } diff --git a/src/qemu.conf b/src/qemu.conf index d9c806776c..c2a53c5cc0 100644 --- a/src/qemu.conf +++ b/src/qemu.conf @@ -60,6 +60,27 @@ # vnc_password = "XYZ12345" +# Enable use of SASL encryption on the VNC server. This requires +# a VNC client which supports the SASL protocol extension. +# Examples include vinagre, virt-viewer and virt-manager +# itself. UltraVNC, RealVNC, TightVNC do not support this +# +# It is necessary to configure /etc/sasl2/qemu.conf to choose +# the desired SASL plugin (eg, GSSPI for Kerberos) +# +# vnc_sasl = 1 + + +# The default SASL configuration file is located in /etc/sasl2/ +# When running libvirtd unprivileged, it may be desirable to +# override the configs in this location. Set this parameter to +# point to the directory, and create a qemu.conf in that location +# +# vnc_sasl_dir = "/some/directory/sasl2" + + + + # The default security driver is SELinux. If SELinux is disabled # on the host, then the security driver will automatically disable # itself. If you wish to disable QEMU SELinux security driver while diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 03f710fa98..9371b02ca9 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -161,6 +161,21 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, } } + p = virConfGetValue (conf, "vnc_sasl"); + CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG); + if (p) driver->vncSASL = p->l; + + p = virConfGetValue (conf, "vnc_sasl_dir"); + CHECK_TYPE ("vnc_sasl_dir", VIR_CONF_STRING); + if (p && p->str) { + VIR_FREE(driver->vncSASLdir); + if (!(driver->vncSASLdir = strdup(p->str))) { + virReportOOMError(NULL); + virConfFree(conf); + return -1; + } + } + virConfFree (conf); return 0; } @@ -838,15 +853,20 @@ int qemudBuildCommandLine(virConnectPtr conn, goto no_memory; \ } while (0) +#define ADD_ENV_PAIR(envname, val) \ + do { \ + char *envval; \ + ADD_ENV_SPACE; \ + if (virAsprintf(&envval, "%s=%s", envname, val) < 0) \ + goto no_memory; \ + qenv[qenvc++] = envval; \ + } while (0) + #define ADD_ENV_COPY(envname) \ do { \ char *val = getenv(envname); \ - char *envval; \ - ADD_ENV_SPACE; \ if (val != NULL) { \ - if (virAsprintf(&envval, "%s=%s", envname, val) < 0) \ - goto no_memory; \ - qenv[qenvc++] = envval; \ + ADD_ENV_PAIR(envname, val); \ } \ } while (0) @@ -1295,6 +1315,15 @@ int qemudBuildCommandLine(virConnectPtr conn, driver->vncTLSx509certdir); } } + + if (driver->vncSASL) { + virBufferAddLit(&opt, ",sasl"); + + if (driver->vncSASLdir) + ADD_ENV_PAIR("SASL_CONF_DIR", driver->vncSASLdir); + + /* TODO: Support ACLs later */ + } } else { virBufferVSprintf(&opt, "%d", vm->def->graphics->data.vnc.port - 5900); diff --git a/src/qemu_conf.h b/src/qemu_conf.h index 00bac80995..d676a80dd7 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -73,9 +73,11 @@ struct qemud_driver { char *stateDir; unsigned int vncTLS : 1; unsigned int vncTLSx509verify : 1; + unsigned int vncSASL : 1; char *vncTLSx509certdir; char *vncListen; char *vncPassword; + char *vncSASLdir; virCapsPtr caps; diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 51442d68c0..fa31e06015 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -621,6 +621,7 @@ qemudShutdown(void) { VIR_FREE(qemu_driver->vncTLSx509certdir); VIR_FREE(qemu_driver->vncListen); VIR_FREE(qemu_driver->vncPassword); + VIR_FREE(qemu_driver->vncSASLdir); /* Free domain callback list */ virDomainEventCallbackListFree(qemu_driver->domainEventCallbacks); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.args new file mode 100644 index 0000000000..29ec4fb100 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test SASL_CONF_DIR=/root/.sasl2 /usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc 127.0.0.1:3,sasl diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml new file mode 100644 index 0000000000..cbaa1dac08 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-sasl.xml @@ -0,0 +1,24 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args new file mode 100644 index 0000000000..bd6a5b0d2f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test SASL_CONF_DIR=/root/.sasl2 /usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc 127.0.0.1:3,tls,x509verify=/etc/pki/tls/qemu,sasl diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml new file mode 100644 index 0000000000..cbaa1dac08 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-tls.xml @@ -0,0 +1,24 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 90b474018c..6cde9af71a 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -213,6 +213,19 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_DRIVE_CACHE_V2); DO_TEST("disk-usb", 0); DO_TEST("graphics-vnc", 0); + + driver.vncSASL = 1; + driver.vncSASLdir = strdup("/root/.sasl2"); + DO_TEST("graphics-vnc-sasl", 0); + driver.vncTLS = 1; + driver.vncTLSx509verify = 1; + driver.vncTLSx509certdir = strdup("/etc/pki/tls/qemu"); + DO_TEST("graphics-vnc-tls", 0); + driver.vncSASL = driver.vncTLSx509verify = driver.vncTLS = 0; + free(driver.vncSASLdir); + free(driver.vncTLSx509certdir); + driver.vncSASLdir = driver.vncTLSx509certdir = NULL; + DO_TEST("graphics-sdl", 0); DO_TEST("graphics-sdl-fullscreen", 0); DO_TEST("input-usbmouse", 0);