Blame qemu-sasl-02-vnc-monitor-info.patch

Daniel P. Berrange 42af21
The current 'info vnc' monitor output just displays the VNC server address
Daniel P. Berrange 42af21
as provided by the -vnc command line flag. This isn't particularly useful
Daniel P. Berrange 42af21
since it doesn't tell you what VNC is actually listening on. eg, if you
Daniel P. Berrange 42af21
use '-vnc :1' it is useful to know whether this translated to '0.0.0.0:5901'
Daniel P. Berrange 42af21
or chose IPv6 ':::5901'.  It is also useful to know the address of the
Daniel P. Berrange 42af21
client that is currently connected. It is also useful to know the active
Daniel P. Berrange 42af21
authentication (if any).
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
This patch tweaks the monitor output to look like:
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
   (qemu) info vnc
Daniel P. Berrange 42af21
    Server:
Daniel P. Berrange 42af21
         address: 0.0.0.0:5902
Daniel P. Berrange 42af21
            auth: vencrypt+x509
Daniel P. Berrange 42af21
    Client: none
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
And when 2 clients are connected
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
   (qemu) info vnc
Daniel P. Berrange 42af21
    Server:
Daniel P. Berrange 42af21
         address: 0.0.0.0:5902
Daniel P. Berrange 42af21
            auth: vencrypt+x509
Daniel P. Berrange 42af21
    Client:
Daniel P. Berrange 42af21
         address: 10.33.6.67:38621
Daniel P. Berrange 42af21
    Client:
Daniel P. Berrange 42af21
         address: 10.33.6.63:38620
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
More data will be added to this later in the patch series...
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
The 'addr_to_string' helper method in this patch is overly generic
Daniel P. Berrange 42af21
for the needs of this patch alone. This is because it will be re-used
Daniel P. Berrange 42af21
by the later SASL patches in this series, where the flexibility is
Daniel P. Berrange 42af21
important.
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
 vnc.c |  137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Daniel P. Berrange 42af21
 1 file changed, 127 insertions(+), 10 deletions(-)
Daniel P. Berrange 42af21
Daniel P. Berrange 42af21
   Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Daniel P. Berrange 42af21
Glauber Costa 8571d0
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
Glauber Costa 8571d0
===================================================================
Glauber Costa 8571d0
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
Glauber Costa 8571d0
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
Daniel P. Berrange 42af21
@@ -166,19 +166,136 @@ struct VncState
Daniel P. Berrange 42af21
 static VncDisplay *vnc_display; /* needed for info vnc */
Daniel P. Berrange 42af21
 static DisplayChangeListener *dcl;
Daniel P. Berrange 42af21
 
Daniel P. Berrange 42af21
+static char *addr_to_string(const char *format,
Daniel P. Berrange 42af21
+			    struct sockaddr_storage *sa,
Daniel P. Berrange 42af21
+			    socklen_t salen) {
Daniel P. Berrange 42af21
+    char *addr;
Daniel P. Berrange 42af21
+    char host[NI_MAXHOST];
Daniel P. Berrange 42af21
+    char serv[NI_MAXSERV];
Daniel P. Berrange 42af21
+    int err;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    if ((err = getnameinfo((struct sockaddr *)sa, salen,
Daniel P. Berrange 42af21
+			   host, sizeof(host),
Daniel P. Berrange 42af21
+			   serv, sizeof(serv),
Daniel P. Berrange 42af21
+			   NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
Daniel P. Berrange 42af21
+	VNC_DEBUG("Cannot resolve address %d: %s\n",
Daniel P. Berrange 42af21
+		  err, gai_strerror(err));
Daniel P. Berrange 42af21
+	return NULL;
Daniel P. Berrange 42af21
+    }
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    if (asprintf(&addr, format, host, serv) < 0)
Daniel P. Berrange 42af21
+	return NULL;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    return addr;
Daniel P. Berrange 42af21
+}
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+static char *vnc_socket_local_addr(const char *format, int fd) {
Daniel P. Berrange 42af21
+    struct sockaddr_storage sa;
Daniel P. Berrange 42af21
+    socklen_t salen;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    salen = sizeof(sa);
Daniel P. Berrange 42af21
+    if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
Daniel P. Berrange 42af21
+	return NULL;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    return addr_to_string(format, &sa, salen);
Daniel P. Berrange 42af21
+}
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+static char *vnc_socket_remote_addr(const char *format, int fd) {
Daniel P. Berrange 42af21
+    struct sockaddr_storage sa;
Daniel P. Berrange 42af21
+    socklen_t salen;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    salen = sizeof(sa);
Daniel P. Berrange 42af21
+    if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
Daniel P. Berrange 42af21
+	return NULL;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    return addr_to_string(format, &sa, salen);
Daniel P. Berrange 42af21
+}
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+static const char *vnc_auth_name(VncDisplay *vd) {
Daniel P. Berrange 42af21
+    switch (vd->auth) {
Daniel P. Berrange 42af21
+    case VNC_AUTH_INVALID:
Daniel P. Berrange 42af21
+	return "invalid";
Daniel P. Berrange 42af21
+    case VNC_AUTH_NONE:
Daniel P. Berrange 42af21
+	return "none";
Daniel P. Berrange 42af21
+    case VNC_AUTH_VNC:
Daniel P. Berrange 42af21
+	return "vnc";
Daniel P. Berrange 42af21
+    case VNC_AUTH_RA2:
Daniel P. Berrange 42af21
+	return "ra2";
Daniel P. Berrange 42af21
+    case VNC_AUTH_RA2NE:
Daniel P. Berrange 42af21
+	return "ra2ne";
Daniel P. Berrange 42af21
+    case VNC_AUTH_TIGHT:
Daniel P. Berrange 42af21
+	return "tight";
Daniel P. Berrange 42af21
+    case VNC_AUTH_ULTRA:
Daniel P. Berrange 42af21
+	return "ultra";
Daniel P. Berrange 42af21
+    case VNC_AUTH_TLS:
Daniel P. Berrange 42af21
+	return "tls";
Daniel P. Berrange 42af21
+    case VNC_AUTH_VENCRYPT:
Daniel P. Berrange 42af21
+#ifdef CONFIG_VNC_TLS
Daniel P. Berrange 42af21
+	switch (vd->subauth) {
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_PLAIN:
Daniel P. Berrange 42af21
+	    return "vencrypt+plain";
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_TLSNONE:
Daniel P. Berrange 42af21
+	    return "vencrypt+tls+none";
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_TLSVNC:
Daniel P. Berrange 42af21
+	    return "vencrypt+tls+vnc";
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_TLSPLAIN:
Daniel P. Berrange 42af21
+	    return "vencrypt+tls+plain";
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_X509NONE:
Daniel P. Berrange 42af21
+	    return "vencrypt+x509+none";
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_X509VNC:
Daniel P. Berrange 42af21
+	    return "vencrypt+x509+vnc";
Daniel P. Berrange 42af21
+	case VNC_AUTH_VENCRYPT_X509PLAIN:
Daniel P. Berrange 42af21
+	    return "vencrypt+x509+plain";
Daniel P. Berrange 42af21
+	default:
Daniel P. Berrange 42af21
+	    return "vencrypt";
Daniel P. Berrange 42af21
+	}
Daniel P. Berrange 42af21
+#else
Daniel P. Berrange 42af21
+	return "vencrypt";
Daniel P. Berrange 42af21
+#endif
Daniel P. Berrange 42af21
+    }
Daniel P. Berrange 42af21
+    return "unknown";
Daniel P. Berrange 42af21
+}
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+#define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+static void do_info_vnc_client(VncState *client)
Daniel P. Berrange 42af21
+{
Daniel P. Berrange 42af21
+    char *clientAddr =
Daniel P. Berrange 42af21
+	vnc_socket_remote_addr("     address: %s:%s\n",
Daniel P. Berrange 42af21
+			       client->csock);
Daniel P. Berrange 42af21
+    if (!clientAddr)
Daniel P. Berrange 42af21
+	return;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+    term_puts("Client:\n");
Daniel P. Berrange 42af21
+    term_puts(clientAddr);
Daniel P. Berrange 42af21
+    free(clientAddr);
Daniel P. Berrange 42af21
+}
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
 void do_info_vnc(void)
Daniel P. Berrange 42af21
 {
Daniel P. Berrange 42af21
-    if (vnc_display == NULL || vnc_display->display == NULL)
Daniel P. Berrange 42af21
-	term_printf("VNC server disabled\n");
Daniel P. Berrange 42af21
-    else {
Daniel P. Berrange 42af21
-	term_printf("VNC server active on: ");
Daniel P. Berrange 42af21
-	term_print_filename(vnc_display->display);
Daniel P. Berrange 42af21
-	term_printf("\n");
Glauber Costa 8571d0
-
Glauber Costa 8571d0
-	if (vnc_display->clients == NULL)
Glauber Costa 8571d0
-	    term_printf("No client connected\n");
Glauber Costa 8571d0
-	else
Glauber Costa 8571d0
-	    term_printf("Client connected\n");
Daniel P. Berrange 42af21
+    if (vnc_display == NULL || vnc_display->display == NULL) {
Daniel P. Berrange 42af21
+	term_printf("Server: disabled\n");
Daniel P. Berrange 42af21
+    } else {
Daniel P. Berrange 42af21
+	char *serverAddr = vnc_socket_local_addr("     address: %s:%s\n",
Daniel P. Berrange 42af21
+						 vnc_display->lsock);
Glauber Costa 8571d0
+
Daniel P. Berrange 42af21
+	if (!serverAddr)
Daniel P. Berrange 42af21
+	    return;
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+	term_puts("Server:\n");
Daniel P. Berrange 42af21
+	term_puts(serverAddr);
Daniel P. Berrange 42af21
+	free(serverAddr);
Daniel P. Berrange 42af21
+	term_printf("        auth: %s\n", vnc_auth_name(vnc_display));
Daniel P. Berrange 42af21
+
Daniel P. Berrange 42af21
+	if (vnc_display->clients) {
Daniel P. Berrange 42af21
+	    VncState *client = vnc_display->clients;
Daniel P. Berrange 42af21
+	    while (client) {
Daniel P. Berrange 42af21
+		do_info_vnc_client(client);
Daniel P. Berrange 42af21
+		client = client->next;
Daniel P. Berrange 42af21
+	    }
Daniel P. Berrange 42af21
+	} else {
Daniel P. Berrange 42af21
+	    term_printf("Client: none\n");
Daniel P. Berrange 42af21
+	}
Daniel P. Berrange 42af21
     }
Daniel P. Berrange 42af21
 }
Daniel P. Berrange 42af21