From a99f4dec46161e16a05f96db09f7617f4dcc9aea Mon Sep 17 00:00:00 2001 From: aliguori Date: Fri, 6 Mar 2009 20:27:32 +0000 Subject: [PATCH] Include auth credentials in 'info vnc' ("Daniel P. Berrange") This patch extends the 'info vnc' monitor output to include information about the VNC client authentication credentials. For clients authenticated using SASL, this will output the username. For clients authenticated using x509 certificates, this will output the x509 distinguished name. Auth can be stacked, so both username & x509 dname may be shown. Server: address: 0.0.0.0:5902 auth: vencrypt+x509+sasl Client: address: 10.33.6.67:38621 x509 dname: C=GB,O=ACME,L=London,ST=London,CN=localhost username: admin Client: address: 10.33.6.63:38620 x509 dname: C=GB,O=ACME,L=London,ST=London,CN=localhost username: admin (cherry picked from commit 1263b7d6131cdaed2c460cf03757aaaf5696ec47) Signed-off-by: Daniel P. Berrange Signed-off-by: Anthony Liguori Signed-off-by: Mark McLoughlin --- vnc-tls.c | 17 +++++++++++++++++ vnc-tls.h | 3 +++ vnc.c | 19 +++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/vnc-tls.c b/vnc-tls.c index 666aa07963..a37a0b43e5 100644 --- a/vnc-tls.c +++ b/vnc-tls.c @@ -241,6 +241,22 @@ int vnc_tls_validate_certificate(struct VncState *vs) return -1; } + if (i == 0) { + size_t dnameSize = 1024; + vs->tls.dname = qemu_malloc(dnameSize); + requery: + if ((ret = gnutls_x509_crt_get_dn (cert, vs->tls.dname, &dnameSize)) != 0) { + if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { + vs->tls.dname = qemu_realloc(vs->tls.dname, dnameSize); + goto requery; + } + gnutls_x509_crt_deinit (cert); + VNC_DEBUG("Cannot get client distinguished name: %s", + gnutls_strerror (ret)); + return -1; + } + } + gnutls_x509_crt_deinit (cert); } @@ -347,6 +363,7 @@ void vnc_tls_client_cleanup(struct VncState *vs) vs->tls.session = NULL; } vs->tls.wiremode = VNC_WIREMODE_CLEAR; + free(vs->tls.dname); } diff --git a/vnc-tls.h b/vnc-tls.h index cda95b9f16..fd0a2d9674 100644 --- a/vnc-tls.h +++ b/vnc-tls.h @@ -55,6 +55,9 @@ struct VncStateTLS { /* Whether data is being TLS encrypted yet */ int wiremode; gnutls_session_t session; + + /* Client's Distinguished Name from the x509 cert */ + char *dname; }; int vnc_tls_client_setup(VncState *vs, int x509Creds); diff --git a/vnc.c b/vnc.c index 33671fdc06..da6884294e 100644 --- a/vnc.c +++ b/vnc.c @@ -156,6 +156,21 @@ static void do_info_vnc_client(VncState *client) term_puts("Client:\n"); term_puts(clientAddr); free(clientAddr); + +#ifdef CONFIG_VNC_TLS + if (client->tls.session && + client->tls.dname) + term_printf(" x509 dname: %s\n", client->tls.dname); + else + term_puts(" x509 dname: none\n"); +#endif +#ifdef CONFIG_VNC_SASL + if (client->sasl.conn && + client->sasl.username) + term_printf(" username: %s\n", client->sasl.username); + else + term_puts(" username: none\n"); +#endif } void do_info_vnc(void) @@ -1832,7 +1847,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 */ - VNC_DEBUG("Reject auth %d\n", (int)data[0]); + VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]); vnc_write_u32(vs, 1); if (vs->minor >= 8) { static const char err[] = "Authentication failed"; @@ -1872,7 +1887,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\n", vs->vd->auth); + VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth); vnc_write_u8(vs, 1); if (vs->minor >= 8) { static const char err[] = "Authentication failed"; -- 2.11.4.GIT