Commit 7b45a00d authored by Daniel P. Berrangé's avatar Daniel P. Berrangé Committed by Gerd Hoffmann
Browse files

ui: remove separate gnutls_session for websockets server



The previous change to the auth scheme handling guarantees we
can never have nested TLS sessions in the VNC websockets server.
Thus we can remove the separate gnutls_session instance.

Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 51941e46
Loading
Loading
Loading
Loading
+29 −41
Original line number Diff line number Diff line
@@ -334,82 +334,77 @@ static int vnc_set_gnutls_priority(gnutls_session_t s, int x509)

int vnc_tls_client_setup(struct VncState *vs,
                         int needX509Creds) {
    VncStateTLS *tls;

    VNC_DEBUG("Do TLS setup\n");
#ifdef CONFIG_VNC_WS
    if (vs->websocket) {
        tls = &vs->ws_tls;
    } else
#endif /* CONFIG_VNC_WS */
    {
        tls = &vs->tls;
    }
    if (vnc_tls_initialize() < 0) {
        VNC_DEBUG("Failed to init TLS\n");
        vnc_client_error(vs);
        return -1;
    }
    if (tls->session == NULL) {
        if (gnutls_init(&tls->session, GNUTLS_SERVER) < 0) {
    if (vs->tls.session == NULL) {
        if (gnutls_init(&vs->tls.session, GNUTLS_SERVER) < 0) {
            vnc_client_error(vs);
            return -1;
        }

        if (gnutls_set_default_priority(tls->session) < 0) {
            gnutls_deinit(tls->session);
            tls->session = NULL;
        if (gnutls_set_default_priority(vs->tls.session) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (vnc_set_gnutls_priority(tls->session, needX509Creds) < 0) {
            gnutls_deinit(tls->session);
            tls->session = NULL;
        if (vnc_set_gnutls_priority(vs->tls.session, needX509Creds) < 0) {
            gnutls_deinit(vs->tls.session);
            vs->tls.session = NULL;
            vnc_client_error(vs);
            return -1;
        }

        if (needX509Creds) {
            gnutls_certificate_server_credentials x509_cred = vnc_tls_initialize_x509_cred(vs->vd);
            gnutls_certificate_server_credentials x509_cred =
                vnc_tls_initialize_x509_cred(vs->vd);
            if (!x509_cred) {
                gnutls_deinit(tls->session);
                tls->session = NULL;
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                vnc_client_error(vs);
                return -1;
            }
            if (gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
                gnutls_deinit(tls->session);
                tls->session = NULL;
            if (gnutls_credentials_set(vs->tls.session,
                                       GNUTLS_CRD_CERTIFICATE, x509_cred) < 0) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                gnutls_certificate_free_credentials(x509_cred);
                vnc_client_error(vs);
                return -1;
            }
            if (vs->vd->tls.x509verify) {
                VNC_DEBUG("Requesting a client certificate\n");
                gnutls_certificate_server_set_request (tls->session, GNUTLS_CERT_REQUEST);
                gnutls_certificate_server_set_request(vs->tls.session,
                                                      GNUTLS_CERT_REQUEST);
            }

        } else {
            gnutls_anon_server_credentials_t anon_cred = vnc_tls_initialize_anon_cred();
            gnutls_anon_server_credentials_t anon_cred =
                vnc_tls_initialize_anon_cred();
            if (!anon_cred) {
                gnutls_deinit(tls->session);
                tls->session = NULL;
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                vnc_client_error(vs);
                return -1;
            }
            if (gnutls_credentials_set(tls->session, GNUTLS_CRD_ANON, anon_cred) < 0) {
                gnutls_deinit(tls->session);
                tls->session = NULL;
            if (gnutls_credentials_set(vs->tls.session,
                                       GNUTLS_CRD_ANON, anon_cred) < 0) {
                gnutls_deinit(vs->tls.session);
                vs->tls.session = NULL;
                gnutls_anon_free_server_credentials(anon_cred);
                vnc_client_error(vs);
                return -1;
            }
        }

        gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr_t)vs);
        gnutls_transport_set_push_function(tls->session, vnc_tls_push);
        gnutls_transport_set_pull_function(tls->session, vnc_tls_pull);
        gnutls_transport_set_ptr(vs->tls.session, (gnutls_transport_ptr_t)vs);
        gnutls_transport_set_push_function(vs->tls.session, vnc_tls_push);
        gnutls_transport_set_pull_function(vs->tls.session, vnc_tls_pull);
    }
    return 0;
}
@@ -422,13 +417,6 @@ void vnc_tls_client_cleanup(struct VncState *vs)
        vs->tls.session = NULL;
    }
    g_free(vs->tls.dname);
#ifdef CONFIG_VNC_WS
    if (vs->ws_tls.session) {
        gnutls_deinit(vs->ws_tls.session);
        vs->ws_tls.session = NULL;
    }
    g_free(vs->ws_tls.dname);
#endif /* CONFIG_VNC_WS */
}


+2 −2
Original line number Diff line number Diff line
@@ -26,12 +26,12 @@

static int vncws_start_tls_handshake(struct VncState *vs)
{
    int ret = gnutls_handshake(vs->ws_tls.session);
    int ret = gnutls_handshake(vs->tls.session);

    if (ret < 0) {
        if (!gnutls_error_is_fatal(ret)) {
            VNC_DEBUG("Handshake interrupted (blocking)\n");
            if (!gnutls_record_get_direction(vs->ws_tls.session)) {
            if (!gnutls_record_get_direction(vs->tls.session)) {
                qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io,
                                    NULL, vs);
            } else {
+2 −16
Original line number Diff line number Diff line
@@ -1343,15 +1343,8 @@ long vnc_client_write_buf(VncState *vs, const uint8_t *data, size_t datalen)
    if (vs->tls.session) {
        ret = vnc_client_write_tls(&vs->tls.session, data, datalen);
    } else {
#ifdef CONFIG_VNC_WS
        if (vs->ws_tls.session) {
            ret = vnc_client_write_tls(&vs->ws_tls.session, data, datalen);
        } else
#endif /* CONFIG_VNC_WS */
#endif /* CONFIG_VNC_TLS */
        {
        ret = send(vs->csock, (const void *)data, datalen, 0);
        }
#ifdef CONFIG_VNC_TLS
    }
#endif /* CONFIG_VNC_TLS */
@@ -1491,15 +1484,8 @@ long vnc_client_read_buf(VncState *vs, uint8_t *data, size_t datalen)
    if (vs->tls.session) {
        ret = vnc_client_read_tls(&vs->tls.session, data, datalen);
    } else {
#ifdef CONFIG_VNC_WS
        if (vs->ws_tls.session) {
            ret = vnc_client_read_tls(&vs->ws_tls.session, data, datalen);
        } else
#endif /* CONFIG_VNC_WS */
#endif /* CONFIG_VNC_TLS */
        {
        ret = qemu_recv(vs->csock, data, datalen, 0);
        }
#ifdef CONFIG_VNC_TLS
    }
#endif /* CONFIG_VNC_TLS */
+0 −3
Original line number Diff line number Diff line
@@ -295,9 +295,6 @@ struct VncState
    VncStateSASL sasl;
#endif
#ifdef CONFIG_VNC_WS
#ifdef CONFIG_VNC_TLS
    VncStateTLS ws_tls;
#endif /* CONFIG_VNC_TLS */
    bool encode_ws;
    bool websocket;
#endif /* CONFIG_VNC_WS */