diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-12-15 17:33:31 +0000 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-12-15 17:33:31 +0000 |
commit | a090ca495e7f6b2bd44d3a5422f17ff4563fae8a (patch) | |
tree | 6fbb31b47b01dc7f1e53c6caaa75692ec8376728 | |
parent | c9687ec616a2a4c969b1458a30d83b186e38e590 (diff) | |
download | xen-a090ca495e7f6b2bd44d3a5422f17ff4563fae8a.tar.gz xen-a090ca495e7f6b2bd44d3a5422f17ff4563fae8a.tar.bz2 xen-a090ca495e7f6b2bd44d3a5422f17ff4563fae8a.zip |
VNC pasword authentication support for the paravirt framebuffer server.
The rules for configuring the password are equivalent of those used
for HVM, but the actual guest config option is a little different as a
result of the recent refactoring of the PVFB config file syntax.
- If the 'vfb' option in the guest config has a 'vncpasswd' parameter
specified
- If the passwd is not zero length, use that
- Else run with no authentication (important as it enables
override of next rule)
- Else-if the xend-config.sxp has a password specified use that
- Else run with no authentication
Example configuration:
- To set an explicit guest password:
vfb = [ "type=vnc,vncunused=1,vnclisten=0.0.0.0,vncpasswd=123456"]
- To disable authentication, overriding any XenD configured
default password
vfb = [ "type=vnc,vncunused=1,vnclisten=0.0.0.0,vncpasswd="]
- To run with default XenD configured password (if any)
vfb = [ "type=vnc,vncunused=1,vnclisten=0.0.0.0"]
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
-rw-r--r-- | .hgignore | 1 | ||||
-rw-r--r-- | tools/python/xen/xend/server/vfbif.py | 12 | ||||
-rw-r--r-- | tools/python/xen/xm/create.py | 4 | ||||
-rw-r--r-- | tools/xenfb/vncfb.c | 93 |
4 files changed, 100 insertions, 10 deletions
@@ -229,3 +229,4 @@ ^unmodified_drivers/linux-2.6/.*\.cmd$ ^unmodified_drivers/linux-2.6/.*\.ko$ ^unmodified_drivers/linux-2.6/.*\.mod\.c$ +^LibVNCServer.* diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py index e24c2284f6..2161ff7331 100644 --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -1,4 +1,5 @@ from xen.xend.server.DevController import DevController +from xen.xend.XendLogging import log from xen.xend.XendError import VmError import xen.xend @@ -41,6 +42,17 @@ class VfbifController(DevController): "--title", self.vm.getName() ] t = config.get("type", None) if t == "vnc": + passwd = None + if config.has_key("vncpasswd"): + passwd = config["vncpasswd"] + else: + passwd = xen.xend.XendRoot.instance().get_vncpasswd_default() + if not(passwd is None or passwd == ""): + self.vm.storeVm("vncpasswd", passwd) + log.debug("Stored a VNC password for vfb access") + else: + log.debug("No VNC passwd configured for vfb access") + # Try to start the vnc backend args = [xen.util.auxbin.pathTo("xen-vncfb")] if config.has_key("vncunused"): diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index aa0c03cac3..b603b922d6 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -284,7 +284,7 @@ gopts.var('usbport', val='PATH', use="""Add a physical USB port to a domain, as specified by the path to that port. This option may be repeated to add more than one port.""") -gopts.var('vfb', val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY", +gopts.var('vfb', val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY,vncpasswd=PASSWORD", fn=append_value, default=[], use="""Make the domain a framebuffer backend. The backend type should be either sdl or vnc. @@ -584,7 +584,7 @@ def configure_vfbs(config_devs, vals): d['type'] = 'sdl' for (k,v) in d.iteritems(): if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display', - 'xauthority', 'type' ]: + 'xauthority', 'type', 'vncpasswd' ]: err("configuration option %s unknown to vfbs" % k) config.append([k,v]) if not d.has_key("display") and os.environ.has_key("DISPLAY"): diff --git a/tools/xenfb/vncfb.c b/tools/xenfb/vncfb.c index 7bb834ee2b..33f55eeb0d 100644 --- a/tools/xenfb/vncfb.c +++ b/tools/xenfb/vncfb.c @@ -212,15 +212,10 @@ static void on_ptr_event(int buttonMask, int x, int y, rfbClientPtr cl) last_y = y; } -static void xenstore_write_vncport(int port, int domid) +static void xenstore_write_vncport(struct xs_handle *xsh, int port, int domid) { - char *buf = NULL, *path; + char *buf, *path; char portstr[10]; - struct xs_handle *xsh = NULL; - - xsh = xs_daemon_open(); - if (xsh == NULL) - return; path = xs_get_domain_path(xsh, domid); if (path == NULL) { @@ -248,6 +243,56 @@ static void xenstore_write_vncport(int port, int domid) } +static int xenstore_read_vncpasswd(struct xs_handle *xsh, int domid, char *pwbuf, int pwbuflen) +{ + char buf[256], *path, *uuid = NULL, *passwd = NULL; + unsigned int len, rc = 0; + + if (xsh == NULL) { + return -1; + } + + path = xs_get_domain_path(xsh, domid); + if (path == NULL) { + fprintf(stderr, "xs_get_domain_path() error\n"); + return -1; + } + + snprintf(buf, 256, "%s/vm", path); + uuid = xs_read(xsh, XBT_NULL, buf, &len); + if (uuid == NULL) { + fprintf(stderr, "xs_read(): uuid get error\n"); + free(path); + return -1; + } + + snprintf(buf, 256, "%s/vncpasswd", uuid); + passwd = xs_read(xsh, XBT_NULL, buf, &len); + if (passwd == NULL) { + free(uuid); + free(path); + return rc; + } + + strncpy(pwbuf, passwd, pwbuflen-1); + pwbuf[pwbuflen-1] = '\0'; + + fprintf(stderr, "Got a VNC password read from XenStore\n"); + + passwd[0] = '\0'; + snprintf(buf, 256, "%s/vncpasswd", uuid); + if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) { + fprintf(stderr, "xs_write() vncpasswd failed\n"); + rc = -1; + } + + free(passwd); + free(uuid); + free(path); + + return rc; +} + static void vnc_update(struct xenfb *xenfb, int x, int y, int w, int h) { rfbScreenInfoPtr server = xenfb->user_data; @@ -281,6 +326,10 @@ int main(int argc, char **argv) char portstr[10]; char *endp; int r; + struct xs_handle *xsh; + char vncpasswd[1024]; + + vncpasswd[0] = '\0'; while ((opt = getopt_long(argc, argv, "d:p:t:u", options, NULL)) != -1) { @@ -353,6 +402,19 @@ int main(int argc, char **argv) exit(1); } + xsh = xs_daemon_open(); + if (xsh == NULL) { + fprintf(stderr, "cannot open connection to xenstore\n"); + exit(1); + } + + + if (xenstore_read_vncpasswd(xsh, domid, vncpasswd, sizeof(vncpasswd)/sizeof(char)) < 0) { + fprintf(stderr, "cannot read VNC password from xenstore\n"); + exit(1); + } + + server = rfbGetScreen(&fake_argc, fake_argv, xenfb->width, xenfb->height, 8, 3, xenfb->depth / 8); @@ -367,6 +429,21 @@ int main(int argc, char **argv) if (unused) server->autoPort = true; + if (vncpasswd[0]) { + char **passwds = malloc(sizeof(char**)*2); + if (!passwds) { + fprintf(stderr, "cannot allocate memory (%s)\n", strerror(errno)); + exit(1); + } + fprintf(stderr, "Registered password\n"); + passwds[0] = vncpasswd; + passwds[1] = NULL; + + server->authPasswdData = passwds; + server->passwordCheck = rfbCheckPasswordByList; + } else { + fprintf(stderr, "Running with no password\n"); + } server->serverFormat.redShift = 16; server->serverFormat.greenShift = 8; server->serverFormat.blueShift = 0; @@ -379,7 +456,7 @@ int main(int argc, char **argv) rfbRunEventLoop(server, -1, true); - xenstore_write_vncport(server->port, domid); + xenstore_write_vncport(xsh, server->port, domid); for (;;) { FD_ZERO(&readfds); |