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 <aliguori@us.ibm.com>
This commit is contained in:
parent
e69ae5c49a
commit
7e7e2ebc94
@ -538,8 +538,8 @@ void start_auth_sasl(VncState *vs)
|
|||||||
|
|
||||||
#ifdef CONFIG_VNC_TLS
|
#ifdef CONFIG_VNC_TLS
|
||||||
/* Inform SASL that we've got an external SSF layer from TLS/x509 */
|
/* Inform SASL that we've got an external SSF layer from TLS/x509 */
|
||||||
if (vs->vd->auth == VNC_AUTH_VENCRYPT &&
|
if (vs->auth == VNC_AUTH_VENCRYPT &&
|
||||||
vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL) {
|
vs->subauth == VNC_AUTH_VENCRYPT_X509SASL) {
|
||||||
gnutls_cipher_algorithm_t cipher;
|
gnutls_cipher_algorithm_t cipher;
|
||||||
sasl_ssf_t ssf;
|
sasl_ssf_t ssf;
|
||||||
|
|
||||||
@ -570,8 +570,8 @@ void start_auth_sasl(VncState *vs)
|
|||||||
#ifdef CONFIG_VNC_TLS
|
#ifdef CONFIG_VNC_TLS
|
||||||
/* Disable SSF, if using TLS+x509+SASL only. TLS without x509
|
/* Disable SSF, if using TLS+x509+SASL only. TLS without x509
|
||||||
is not sufficiently strong */
|
is not sufficiently strong */
|
||||||
|| (vs->vd->auth == VNC_AUTH_VENCRYPT &&
|
|| (vs->auth == VNC_AUTH_VENCRYPT &&
|
||||||
vs->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL)
|
vs->subauth == VNC_AUTH_VENCRYPT_X509SASL)
|
||||||
#endif /* CONFIG_VNC_TLS */
|
#endif /* CONFIG_VNC_TLS */
|
||||||
) {
|
) {
|
||||||
/* If we've got TLS or UNIX domain sock, we don't care about SSF */
|
/* If we've got TLS or UNIX domain sock, we don't care about SSF */
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
static void start_auth_vencrypt_subauth(VncState *vs)
|
static void start_auth_vencrypt_subauth(VncState *vs)
|
||||||
{
|
{
|
||||||
switch (vs->vd->subauth) {
|
switch (vs->subauth) {
|
||||||
case VNC_AUTH_VENCRYPT_TLSNONE:
|
case VNC_AUTH_VENCRYPT_TLSNONE:
|
||||||
case VNC_AUTH_VENCRYPT_X509NONE:
|
case VNC_AUTH_VENCRYPT_X509NONE:
|
||||||
VNC_DEBUG("Accept TLS auth none\n");
|
VNC_DEBUG("Accept TLS auth none\n");
|
||||||
@ -51,7 +51,7 @@ static void start_auth_vencrypt_subauth(VncState *vs)
|
|||||||
#endif /* CONFIG_VNC_SASL */
|
#endif /* CONFIG_VNC_SASL */
|
||||||
|
|
||||||
default: /* Should not be possible, but just in case */
|
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);
|
vnc_write_u8(vs, 1);
|
||||||
if (vs->minor >= 8) {
|
if (vs->minor >= 8) {
|
||||||
static const char err[] = "Unsupported authentication type";
|
static const char err[] = "Unsupported authentication type";
|
||||||
@ -110,17 +110,17 @@ static void vnc_tls_handshake_io(void *opaque) {
|
|||||||
|
|
||||||
|
|
||||||
#define NEED_X509_AUTH(vs) \
|
#define NEED_X509_AUTH(vs) \
|
||||||
((vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
|
((vs)->subauth == VNC_AUTH_VENCRYPT_X509NONE || \
|
||||||
(vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
|
(vs)->subauth == VNC_AUTH_VENCRYPT_X509VNC || \
|
||||||
(vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509PLAIN || \
|
(vs)->subauth == VNC_AUTH_VENCRYPT_X509PLAIN || \
|
||||||
(vs)->vd->subauth == VNC_AUTH_VENCRYPT_X509SASL)
|
(vs)->subauth == VNC_AUTH_VENCRYPT_X509SASL)
|
||||||
|
|
||||||
|
|
||||||
static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
|
static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
int auth = read_u32(data, 0);
|
int auth = read_u32(data, 0);
|
||||||
|
|
||||||
if (auth != vs->vd->subauth) {
|
if (auth != vs->subauth) {
|
||||||
VNC_DEBUG("Rejecting auth %d\n", auth);
|
VNC_DEBUG("Rejecting auth %d\n", auth);
|
||||||
vnc_write_u8(vs, 0); /* Reject auth */
|
vnc_write_u8(vs, 0); /* Reject auth */
|
||||||
vnc_flush(vs);
|
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_flush(vs);
|
||||||
vnc_client_error(vs);
|
vnc_client_error(vs);
|
||||||
} else {
|
} 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, 0); /* Accept version */
|
||||||
vnc_write_u8(vs, 1); /* Number of sub-auths */
|
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_flush(vs);
|
||||||
vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
|
vnc_read_when(vs, protocol_client_vencrypt_auth, 4);
|
||||||
}
|
}
|
||||||
|
39
ui/vnc.c
39
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
|
/* We only advertise 1 auth scheme at a time, so client
|
||||||
* must pick the one we sent. Verify this */
|
* 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_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
|
||||||
vnc_write_u32(vs, 1);
|
vnc_write_u32(vs, 1);
|
||||||
if (vs->minor >= 8) {
|
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);
|
vnc_client_error(vs);
|
||||||
} else { /* Accept requested auth */
|
} else { /* Accept requested auth */
|
||||||
VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
|
VNC_DEBUG("Client requested auth %d\n", (int)data[0]);
|
||||||
switch (vs->vd->auth) {
|
switch (vs->auth) {
|
||||||
case VNC_AUTH_NONE:
|
case VNC_AUTH_NONE:
|
||||||
VNC_DEBUG("Accept auth none\n");
|
VNC_DEBUG("Accept auth none\n");
|
||||||
if (vs->minor >= 8) {
|
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 */
|
#endif /* CONFIG_VNC_SASL */
|
||||||
|
|
||||||
default: /* Should not be possible, but just in case */
|
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);
|
vnc_write_u8(vs, 1);
|
||||||
if (vs->minor >= 8) {
|
if (vs->minor >= 8) {
|
||||||
static const char err[] = "Authentication failed";
|
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;
|
vs->minor = 3;
|
||||||
|
|
||||||
if (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_DEBUG("Tell client auth none\n");
|
||||||
vnc_write_u32(vs, vs->vd->auth);
|
vnc_write_u32(vs, vs->auth);
|
||||||
vnc_flush(vs);
|
vnc_flush(vs);
|
||||||
start_client_init(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_DEBUG("Tell client VNC auth\n");
|
||||||
vnc_write_u32(vs, vs->vd->auth);
|
vnc_write_u32(vs, vs->auth);
|
||||||
vnc_flush(vs);
|
vnc_flush(vs);
|
||||||
start_auth_vnc(vs);
|
start_auth_vnc(vs);
|
||||||
} else {
|
} 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_write_u32(vs, VNC_AUTH_INVALID);
|
||||||
vnc_flush(vs);
|
vnc_flush(vs);
|
||||||
vnc_client_error(vs);
|
vnc_client_error(vs);
|
||||||
}
|
}
|
||||||
} else {
|
} 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, 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_read_when(vs, protocol_client_auth, 1);
|
||||||
vnc_flush(vs);
|
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));
|
VncState *vs = qemu_mallocz(sizeof(VncState));
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
vs->csock = csock;
|
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));
|
vs->lossy_rect = qemu_mallocz(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
|
||||||
for (i = 0; i < VNC_STAT_ROWS; ++i) {
|
for (i = 0; i < VNC_STAT_ROWS; ++i) {
|
||||||
vs->lossy_rect[i] = qemu_mallocz(VNC_STAT_COLS * sizeof (uint8_t));
|
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);
|
int csock = qemu_accept(vs->lsock, (struct sockaddr *)&addr, &addrlen);
|
||||||
if (csock != -1) {
|
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 {
|
} else {
|
||||||
int csock = vs->lsock;
|
int csock = vs->lsock;
|
||||||
vs->lsock = -1;
|
vs->lsock = -1;
|
||||||
vnc_connect(vs, csock);
|
vnc_connect(vs, csock, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
2
ui/vnc.h
2
ui/vnc.h
@ -256,8 +256,10 @@ struct VncState
|
|||||||
int major;
|
int major;
|
||||||
int minor;
|
int minor;
|
||||||
|
|
||||||
|
int auth;
|
||||||
char challenge[VNC_AUTH_CHALLENGE_SIZE];
|
char challenge[VNC_AUTH_CHALLENGE_SIZE];
|
||||||
#ifdef CONFIG_VNC_TLS
|
#ifdef CONFIG_VNC_TLS
|
||||||
|
int subauth; /* Used by VeNCrypt */
|
||||||
VncStateTLS tls;
|
VncStateTLS tls;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_VNC_SASL
|
#ifdef CONFIG_VNC_SASL
|
||||||
|
Loading…
Reference in New Issue
Block a user