From 7e7e2ebc942da8285931ceabf12823e165dced8b Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Thu, 23 Jun 2011 13:31:41 +0100 Subject: Store VNC auth scheme per-client as well as per-server A future patch will introduce a situation where different clients may have different authentication schemes set. When a new client arrives, copy the 'auth' and 'subauth' fields from VncDisplay into the client's VncState, and use the latter in all authentication functions. * ui/vnc.h: Add 'auth' and 'subauth' to VncState * ui/vnc-auth-sasl.c, ui/vnc-auth-vencrypt.c, ui/vnc.c: Make auth functions pull auth scheme from VncState instead of VncDisplay Signed-off-by: Anthony Liguori --- ui/vnc-auth-sasl.c | 8 ++++---- ui/vnc-auth-vencrypt.c | 18 +++++++++--------- ui/vnc.c | 39 ++++++++++++++++++++++++++------------- ui/vnc.h | 2 ++ 4 files changed, 41 insertions(+), 26 deletions(-) (limited to 'ui') diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c index 17a621a2b..8aac5ec00 100644 --- a/ui/vnc-auth-sasl.c +++ b/ui/vnc-auth-sasl.c @@ -538,8 +538,8 @@ void start_auth_sasl(VncState *vs) #ifdef CONFIG_VNC_TLS /* Inform SASL that we've got an external SSF layer from TLS/x509 */ - if (vs->vd->auth == VNC_AUTH_VENCRYPT && - vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) { + if (vs->auth == VNC_AUTH_VENCRYPT && + vs->subauth == VNC_AUTH_VENCRYPT_X509SASL) { gnutls_cipher_algorithm_t cipher; sasl_ssf_t ssf; @@ -570,8 +570,8 @@ void start_auth_sasl(VncState *vs) #ifdef CONFIG_VNC_TLS /* Disable SSF, if using TLS+x509+SASL only. TLS without x509 is not sufficiently strong */ - || (vs->vd->auth == VNC_AUTH_VENCRYPT && - vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) + || (vs->auth == VNC_AUTH_VENCRYPT && + vs->subauth == VNC_AUTH_VENCRYPT_X509SASL) #endif /* CONFIG_VNC_TLS */ ) { /* If we've got TLS or UNIX domain sock, we don't care about SSF */ diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c index 07c169186..674ba97dc 100644 --- a/ui/vnc-auth-vencrypt.c +++ b/ui/vnc-auth-vencrypt.c @@ -29,7 +29,7 @@ static void start_auth_vencrypt_subauth(VncState *vs) { - switch (vs->vd->subauth) { + switch (vs->subauth) { case VNC_AUTH_VENCRYPT_TLSNONE: case VNC_AUTH_VENCRYPT_X509NONE: VNC_DEBUG("Accept TLS auth none\n"); @@ -51,7 +51,7 @@ static void start_auth_vencrypt_subauth(VncState *vs) #endif /* CONFIG_VNC_SASL */ default: /* Should not be possible, but just in case */ - VNC_DEBUG("Reject subauth %d server bug\n", vs->vd->auth); + VNC_DEBUG("Reject subauth %d server bug\n", vs->auth); vnc_write_u8(vs, 1); if (vs->minor >= 8) { static const char err[] = "Unsupported authentication type"; @@ -110,17 +110,17 @@ static void vnc_tls_handshake_io(void *opaque) { #define NEED_X509_AUTH(vs) \ - ((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \ - (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \ - (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN || \ - (vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) + ((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \ + (vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \ + (vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN || \ + (vs)->subauth == VNC_AUTH_VENCRYPT_X509SASL) static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len) { int auth = read_u32(data, 0); - if (auth != vs->vd->subauth) { + if (auth != vs->subauth) { VNC_DEBUG("Rejecting auth %d\n", auth); vnc_write_u8(vs, 0); /* Reject auth */ vnc_flush(vs); @@ -153,10 +153,10 @@ static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len vnc_flush(vs); vnc_client_error(vs); } else { - VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth); + VNC_DEBUG("Sending allowed auth %d\n", vs->subauth); vnc_write_u8(vs, 0); /* Accept version */ vnc_write_u8(vs, 1); /* Number of sub-auths */ - vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */ + vnc_write_u32(vs, vs->subauth); /* The supported auth */ vnc_flush(vs); vnc_read_when(vs, protocol_client_vencrypt_auth, 4); } diff --git a/ui/vnc.c b/ui/vnc.c index 14f2930d1..39b5b51fa 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -2124,7 +2124,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) { /* We only advertise 1 auth scheme at a time, so client * must pick the one we sent. Verify this */ - if (data[0] != vs->vd->auth) { /* Reject auth */ + if (data[0] != vs->auth) { /* Reject auth */ VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]); vnc_write_u32(vs, 1); if (vs->minor >= 8) { @@ -2135,7 +2135,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) vnc_client_error(vs); } else { /* Accept requested auth */ VNC_DEBUG("Client requested auth %d\n", (int)data[0]); - switch (vs->vd->auth) { + switch (vs->auth) { case VNC_AUTH_NONE: VNC_DEBUG("Accept auth none\n"); if (vs->minor >= 8) { @@ -2165,7 +2165,7 @@ static int protocol_client_auth(VncState *vs, uint8_t *data, size_t len) #endif /* CONFIG_VNC_SASL */ default: /* Should not be possible, but just in case */ - VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth); + VNC_DEBUG("Reject auth %d server code bug\n", vs->auth); vnc_write_u8(vs, 1); if (vs->minor >= 8) { static const char err[] = "Authentication failed"; @@ -2210,26 +2210,26 @@ static int protocol_version(VncState *vs, uint8_t *version, size_t len) vs->minor = 3; if (vs->minor == 3) { - if (vs->vd->auth == VNC_AUTH_NONE) { + if (vs->auth == VNC_AUTH_NONE) { VNC_DEBUG("Tell client auth none\n"); - vnc_write_u32(vs, vs->vd->auth); + vnc_write_u32(vs, vs->auth); vnc_flush(vs); start_client_init(vs); - } else if (vs->vd->auth == VNC_AUTH_VNC) { + } else if (vs->auth == VNC_AUTH_VNC) { VNC_DEBUG("Tell client VNC auth\n"); - vnc_write_u32(vs, vs->vd->auth); + vnc_write_u32(vs, vs->auth); vnc_flush(vs); start_auth_vnc(vs); } else { - VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->vd->auth); + VNC_DEBUG("Unsupported auth %d for protocol 3.3\n", vs->auth); vnc_write_u32(vs, VNC_AUTH_INVALID); vnc_flush(vs); vnc_client_error(vs); } } else { - VNC_DEBUG("Telling client we support auth %d\n", vs->vd->auth); + VNC_DEBUG("Telling client we support auth %d\n", vs->auth); vnc_write_u8(vs, 1); /* num auth */ - vnc_write_u8(vs, vs->vd->auth); + vnc_write_u8(vs, vs->auth); vnc_read_when(vs, protocol_client_auth, 1); vnc_flush(vs); } @@ -2494,12 +2494,25 @@ static void vnc_remove_timer(VncDisplay *vd) } } -static void vnc_connect(VncDisplay *vd, int csock) +static void vnc_connect(VncDisplay *vd, int csock, int skipauth) { VncState *vs = qemu_mallocz(sizeof(VncState)); int i; vs->csock = csock; + + if (skipauth) { + vs->auth = VNC_AUTH_NONE; +#ifdef CONFIG_VNC_TLS + vs->subauth = VNC_AUTH_INVALID; +#endif + } else { + vs->auth = vd->auth; +#ifdef CONFIG_VNC_TLS + vs->subauth = vd->subauth; +#endif + } + vs->lossy_rect = qemu_mallocz(VNC_STAT_ROWS * sizeof (*vs->lossy_rect)); for (i = 0; i < VNC_STAT_ROWS; ++i) { vs->lossy_rect[i] = qemu_mallocz(VNC_STAT_COLS * sizeof (uint8_t)); @@ -2557,7 +2570,7 @@ static void vnc_listen_read(void *opaque) int csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen); if (csock != -1) { - vnc_connect(vs, csock); + vnc_connect(vs, csock, 0); } } @@ -2887,7 +2900,7 @@ int vnc_display_open(DisplayState *ds, const char *display) } else { int csock = vs->lsock; vs->lsock = -1; - vnc_connect(vs, csock); + vnc_connect(vs, csock, 0); } return 0; diff --git a/ui/vnc.h b/ui/vnc.h index f10c5dc4e..66689f1d6 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -256,8 +256,10 @@ struct VncState int major; int minor; + int auth; char challenge[VNC_AUTH_CHALLENGE_SIZE]; #ifdef CONFIG_VNC_TLS + int subauth; /* Used by VeNCrypt */ VncStateTLS tls; #endif #ifdef CONFIG_VNC_SASL -- cgit v1.2.3