diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2015-08-06 14:39:32 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2015-09-15 15:20:55 +0100 |
commit | 3e305e4a4752f70c0b5c3cf5b43ec957881714f7 (patch) | |
tree | e3ba8537a1753b436804b676aaddbdcc9448bb15 /ui/vnc-auth-vencrypt.c | |
parent | fdd1ab6ad5c27a1564a1c73045908736b228458b (diff) |
ui: convert VNC server to use QCryptoTLSSession
Switch VNC server over to using the QCryptoTLSSession object
for the TLS session. This removes the direct use of gnutls
from the VNC server code. It also removes most knowledge
about TLS certificate handling from the VNC server code.
This has the nice effect that all the CONFIG_VNC_TLS
conditionals go away and the user gets an actual error
message when requesting TLS instead of it being silently
ignored.
With this change, the existing configuration options for
enabling TLS with -vnc are deprecated.
Old syntax for anon-DH credentials:
-vnc hostname:0,tls
New syntax:
-object tls-creds-anon,id=tls0,endpoint=server \
-vnc hostname:0,tls-creds=tls0
Old syntax for x509 credentials, no client certs:
-vnc hostname:0,tls,x509=/path/to/certs
New syntax:
-object tls-creds-x509,id=tls0,dir=/path/to/certs,endpoint=server,verify-peer=no \
-vnc hostname:0,tls-creds=tls0
Old syntax for x509 credentials, requiring client certs:
-vnc hostname:0,tls,x509verify=/path/to/certs
New syntax:
-object tls-creds-x509,id=tls0,dir=/path/to/certs,endpoint=server,verify-peer=yes \
-vnc hostname:0,tls-creds=tls0
This aligns VNC with the way TLS credentials are to be
configured in the future for chardev, nbd and migration
backends. It also has the benefit that the same TLS
credentials can be shared across multiple VNC server
instances, if desired.
If someone uses the deprecated syntax, it will internally
result in the creation of a 'tls-creds' object with an ID
based on the VNC server ID. This allows backwards compat
with the CLI syntax, while still deleting all the original
TLS code from the VNC server.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'ui/vnc-auth-vencrypt.c')
-rw-r--r-- | ui/vnc-auth-vencrypt.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c index 8fc965b4ad..44ac2fae63 100644 --- a/ui/vnc-auth-vencrypt.c +++ b/ui/vnc-auth-vencrypt.c @@ -67,38 +67,42 @@ static void vnc_tls_handshake_io(void *opaque); static int vnc_start_vencrypt_handshake(VncState *vs) { - int ret; - - if ((ret = gnutls_handshake(vs->tls.session)) < 0) { - if (!gnutls_error_is_fatal(ret)) { - VNC_DEBUG("Handshake interrupted (blocking)\n"); - if (!gnutls_record_get_direction(vs->tls.session)) - qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs); - else - qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs); - return 0; - } - VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret)); - vnc_client_error(vs); - return -1; + Error *err = NULL; + + if (qcrypto_tls_session_handshake(vs->tls, &err) < 0) { + goto error; } - if (vs->vd->tls.x509verify) { - if (vnc_tls_validate_certificate(vs) < 0) { - VNC_DEBUG("Client verification failed\n"); - vnc_client_error(vs); - return -1; - } else { - VNC_DEBUG("Client verification passed\n"); + switch (qcrypto_tls_session_get_handshake_status(vs->tls)) { + case QCRYPTO_TLS_HANDSHAKE_COMPLETE: + VNC_DEBUG("Handshake done, checking credentials\n"); + if (qcrypto_tls_session_check_credentials(vs->tls, &err) < 0) { + goto error; } - } + VNC_DEBUG("Client verification passed, starting TLS I/O\n"); + qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs); + + start_auth_vencrypt_subauth(vs); + break; - VNC_DEBUG("Handshake done, switching to TLS data mode\n"); - qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs); + case QCRYPTO_TLS_HANDSHAKE_RECVING: + VNC_DEBUG("Handshake interrupted (blocking read)\n"); + qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs); + break; - start_auth_vencrypt_subauth(vs); + case QCRYPTO_TLS_HANDSHAKE_SENDING: + VNC_DEBUG("Handshake interrupted (blocking write)\n"); + qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs); + break; + } return 0; + + error: + VNC_DEBUG("Handshake failed %s\n", error_get_pretty(err)); + error_free(err); + vnc_client_error(vs); + return -1; } static void vnc_tls_handshake_io(void *opaque) @@ -110,14 +114,6 @@ static void vnc_tls_handshake_io(void *opaque) } - -#define NEED_X509_AUTH(vs) \ - ((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); @@ -128,15 +124,29 @@ static int protocol_client_vencrypt_auth(VncState *vs, uint8_t *data, size_t len vnc_flush(vs); vnc_client_error(vs); } else { + Error *err = NULL; VNC_DEBUG("Accepting auth %d, setting up TLS for handshake\n", auth); vnc_write_u8(vs, 1); /* Accept auth */ vnc_flush(vs); - if (vnc_tls_client_setup(vs, NEED_X509_AUTH(vs)) < 0) { - VNC_DEBUG("Failed to setup TLS\n"); + vs->tls = qcrypto_tls_session_new(vs->vd->tlscreds, + NULL, + vs->vd->tlsaclname, + QCRYPTO_TLS_CREDS_ENDPOINT_SERVER, + &err); + if (!vs->tls) { + VNC_DEBUG("Failed to setup TLS %s\n", + error_get_pretty(err)); + error_free(err); + vnc_client_error(vs); return 0; } + qcrypto_tls_session_set_callbacks(vs->tls, + vnc_tls_push, + vnc_tls_pull, + vs); + VNC_DEBUG("Start TLS VeNCrypt handshake process\n"); if (vnc_start_vencrypt_handshake(vs) < 0) { VNC_DEBUG("Failed to start TLS handshake\n"); |