42af212
This patch extends the 'info vnc' monitor output to include information
42af212
about the VNC client authentication credentials.
42af212
42af212
For clients authenticated using SASL, this will output the username.
42af212
42af212
For clients authenticated using x509 certificates, this will output
42af212
the x509 distinguished name.
42af212
42af212
Auth can be stacked, so both username & x509 dname may be shown.
42af212
42af212
    Server:
42af212
         address: 0.0.0.0:5902
42af212
            auth: vencrypt+x509+sasl
42af212
    Client:
42af212
         address: 10.33.6.67:38621
42af212
      x509 dname: C=GB,O=ACME,L=London,ST=London,CN=localhost
42af212
        username: admin
42af212
    Client:
42af212
         address: 10.33.6.63:38620
42af212
      x509 dname: C=GB,O=ACME,L=London,ST=London,CN=localhost
42af212
        username: admin
42af212
42af212
42af212
42af212
 vnc-tls.c |   17 +++++++++++++++++
42af212
 vnc-tls.h |    3 +++
42af212
 vnc.c     |   19 +++++++++++++++++--
42af212
 3 files changed, 37 insertions(+), 2 deletions(-)
42af212
42af212
   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
42af212
42af212
diff -r 440be37a35ea vnc-tls.c
42af212
--- a/vnc-tls.c	Fri Feb 20 11:46:26 2009 +0000
42af212
+++ b/vnc-tls.c	Fri Feb 20 11:47:52 2009 +0000
42af212
@@ -241,6 +241,22 @@ int vnc_tls_validate_certificate(struct 
42af212
 	    return -1;
42af212
 	}
42af212
 
42af212
+	if (i == 0) {
42af212
+	    size_t dnameSize = 1024;
42af212
+	    vs->tls.dname = qemu_malloc(dnameSize);
42af212
+	requery:
42af212
+	    if ((ret = gnutls_x509_crt_get_dn (cert, vs->tls.dname, &dnameSize)) != 0) {
42af212
+		if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
42af212
+		    vs->tls.dname = qemu_realloc(vs->tls.dname, dnameSize);
42af212
+		    goto requery;
42af212
+		}
42af212
+		gnutls_x509_crt_deinit (cert);
42af212
+		VNC_DEBUG("Cannot get client distinguished name: %s",
42af212
+			  gnutls_strerror (ret));
42af212
+		return -1;
42af212
+	    }
42af212
+	}
42af212
+
42af212
 	gnutls_x509_crt_deinit (cert);
42af212
     }
42af212
 
42af212
@@ -347,6 +363,7 @@ void vnc_tls_client_cleanup(struct VncSt
42af212
 	vs->tls.session = NULL;
42af212
     }
42af212
     vs->tls.wiremode = VNC_WIREMODE_CLEAR;
42af212
+    free(vs->tls.dname);
42af212
 }
42af212
 
42af212
 
42af212
diff -r 440be37a35ea vnc-tls.h
42af212
--- a/vnc-tls.h	Fri Feb 20 11:46:26 2009 +0000
42af212
+++ b/vnc-tls.h	Fri Feb 20 11:47:52 2009 +0000
42af212
@@ -55,6 +55,9 @@ struct VncStateTLS {
42af212
     /* Whether data is being TLS encrypted yet */
42af212
     int wiremode;
42af212
     gnutls_session_t session;
42af212
+
42af212
+    /* Client's Distinguished Name from the x509 cert */
42af212
+    char *dname;
42af212
 };
42af212
 
42af212
 int vnc_tls_client_setup(VncState *vs, int x509Creds);
42af212
diff -r 440be37a35ea vnc.c
42af212
--- a/vnc.c	Fri Feb 20 11:46:26 2009 +0000
42af212
+++ b/vnc.c	Fri Feb 20 11:47:52 2009 +0000
42af212
@@ -156,6 +156,21 @@ static void do_info_vnc_client(VncState 
42af212
     term_puts("Client:\n");
42af212
     term_puts(clientAddr);
42af212
     free(clientAddr);
42af212
+
42af212
+#ifdef CONFIG_VNC_TLS
42af212
+    if (client->tls.session &&
42af212
+	client->tls.dname)
42af212
+	term_printf("  x509 dname: %s\n", client->tls.dname);
42af212
+    else
42af212
+	term_puts("  x509 dname: none\n");
42af212
+#endif
42af212
+#ifdef CONFIG_VNC_SASL
42af212
+    if (client->sasl.conn &&
42af212
+	client->sasl.username)
42af212
+	term_printf("    username: %s\n", client->sasl.username);
42af212
+    else
42af212
+	term_puts("    username: none\n");
42af212
+#endif
42af212
 }
42af212
 
42af212
 void do_info_vnc(void)
42af212
@@ -1823,7 +1838,7 @@ static int protocol_client_auth(VncState
42af212
     /* We only advertise 1 auth scheme at a time, so client
42af212
      * must pick the one we sent. Verify this */
42af212
     if (data[0] != vs->vd->auth) { /* Reject auth */
42af212
-       VNC_DEBUG("Reject auth %d\n", (int)data[0]);
42af212
+       VNC_DEBUG("Reject auth %d because it didn't match advertized\n", (int)data[0]);
42af212
        vnc_write_u32(vs, 1);
42af212
        if (vs->minor >= 8) {
42af212
            static const char err[] = "Authentication failed";
42af212
@@ -1863,7 +1878,7 @@ static int protocol_client_auth(VncState
42af212
 #endif /* CONFIG_VNC_SASL */
42af212
 
42af212
        default: /* Should not be possible, but just in case */
42af212
-           VNC_DEBUG("Reject auth %d\n", vs->vd->auth);
42af212
+           VNC_DEBUG("Reject auth %d server code bug\n", vs->vd->auth);
42af212
            vnc_write_u8(vs, 1);
42af212
            if (vs->minor >= 8) {
42af212
                static const char err[] = "Authentication failed";