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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user