Glauber Costa 47b0758
Index: qemu-kvm-0.10/qemu/vnc.c
Glauber Costa 47b0758
===================================================================
Glauber Costa 47b0758
--- qemu-kvm-0.10.orig/qemu/vnc.c
Glauber Costa 47b0758
+++ qemu-kvm-0.10/qemu/vnc.c
Glauber Costa 47b0758
@@ -166,19 +166,136 @@ struct VncState
Glauber Costa 47b0758
 static VncDisplay *vnc_display; /* needed for info vnc */
Glauber Costa 47b0758
 static DisplayChangeListener *dcl;
Glauber Costa 47b0758
 
Glauber Costa 47b0758
+static char *addr_to_string(const char *format,
Glauber Costa 47b0758
+			    struct sockaddr_storage *sa,
Glauber Costa 47b0758
+			    socklen_t salen) {
Glauber Costa 47b0758
+    char *addr;
Glauber Costa 47b0758
+    char host[NI_MAXHOST];
Glauber Costa 47b0758
+    char serv[NI_MAXSERV];
Glauber Costa 47b0758
+    int err;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    if ((err = getnameinfo((struct sockaddr *)sa, salen,
Glauber Costa 47b0758
+			   host, sizeof(host),
Glauber Costa 47b0758
+			   serv, sizeof(serv),
Glauber Costa 47b0758
+			   NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
Glauber Costa 47b0758
+	VNC_DEBUG("Cannot resolve address %d: %s\n",
Glauber Costa 47b0758
+		  err, gai_strerror(err));
Glauber Costa 47b0758
+	return NULL;
Glauber Costa 47b0758
+    }
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    if (asprintf(&addr, format, host, serv) < 0)
Glauber Costa 47b0758
+	return NULL;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    return addr;
Glauber Costa 47b0758
+}
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+static char *vnc_socket_local_addr(const char *format, int fd) {
Glauber Costa 47b0758
+    struct sockaddr_storage sa;
Glauber Costa 47b0758
+    socklen_t salen;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    salen = sizeof(sa);
Glauber Costa 47b0758
+    if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
Glauber Costa 47b0758
+	return NULL;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    return addr_to_string(format, &sa, salen);
Glauber Costa 47b0758
+}
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+static char *vnc_socket_remote_addr(const char *format, int fd) {
Glauber Costa 47b0758
+    struct sockaddr_storage sa;
Glauber Costa 47b0758
+    socklen_t salen;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    salen = sizeof(sa);
Glauber Costa 47b0758
+    if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
Glauber Costa 47b0758
+	return NULL;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    return addr_to_string(format, &sa, salen);
Glauber Costa 47b0758
+}
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+static const char *vnc_auth_name(VncDisplay *vd) {
Glauber Costa 47b0758
+    switch (vd->auth) {
Glauber Costa 47b0758
+    case VNC_AUTH_INVALID:
Glauber Costa 47b0758
+	return "invalid";
Glauber Costa 47b0758
+    case VNC_AUTH_NONE:
Glauber Costa 47b0758
+	return "none";
Glauber Costa 47b0758
+    case VNC_AUTH_VNC:
Glauber Costa 47b0758
+	return "vnc";
Glauber Costa 47b0758
+    case VNC_AUTH_RA2:
Glauber Costa 47b0758
+	return "ra2";
Glauber Costa 47b0758
+    case VNC_AUTH_RA2NE:
Glauber Costa 47b0758
+	return "ra2ne";
Glauber Costa 47b0758
+    case VNC_AUTH_TIGHT:
Glauber Costa 47b0758
+	return "tight";
Glauber Costa 47b0758
+    case VNC_AUTH_ULTRA:
Glauber Costa 47b0758
+	return "ultra";
Glauber Costa 47b0758
+    case VNC_AUTH_TLS:
Glauber Costa 47b0758
+	return "tls";
Glauber Costa 47b0758
+    case VNC_AUTH_VENCRYPT:
Glauber Costa 47b0758
+#ifdef CONFIG_VNC_TLS
Glauber Costa 47b0758
+	switch (vd->subauth) {
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_PLAIN:
Glauber Costa 47b0758
+	    return "vencrypt+plain";
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_TLSNONE:
Glauber Costa 47b0758
+	    return "vencrypt+tls+none";
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_TLSVNC:
Glauber Costa 47b0758
+	    return "vencrypt+tls+vnc";
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_TLSPLAIN:
Glauber Costa 47b0758
+	    return "vencrypt+tls+plain";
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_X509NONE:
Glauber Costa 47b0758
+	    return "vencrypt+x509+none";
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_X509VNC:
Glauber Costa 47b0758
+	    return "vencrypt+x509+vnc";
Glauber Costa 47b0758
+	case VNC_AUTH_VENCRYPT_X509PLAIN:
Glauber Costa 47b0758
+	    return "vencrypt+x509+plain";
Glauber Costa 47b0758
+	default:
Glauber Costa 47b0758
+	    return "vencrypt";
Glauber Costa 47b0758
+	}
Glauber Costa 47b0758
+#else
Glauber Costa 47b0758
+	return "vencrypt";
Glauber Costa 47b0758
+#endif
Glauber Costa 47b0758
+    }
Glauber Costa 47b0758
+    return "unknown";
Glauber Costa 47b0758
+}
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+#define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+static void do_info_vnc_client(VncState *client)
Glauber Costa 47b0758
+{
Glauber Costa 47b0758
+    char *clientAddr =
Glauber Costa 47b0758
+	vnc_socket_remote_addr("     address: %s:%s\n",
Glauber Costa 47b0758
+			       client->csock);
Glauber Costa 47b0758
+    if (!clientAddr)
Glauber Costa 47b0758
+	return;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+    term_puts("Client:\n");
Glauber Costa 47b0758
+    term_puts(clientAddr);
Glauber Costa 47b0758
+    free(clientAddr);
Glauber Costa 47b0758
+}
Glauber Costa 47b0758
+
Glauber Costa 47b0758
 void do_info_vnc(void)
Glauber Costa 47b0758
 {
Glauber Costa 47b0758
-    if (vnc_display == NULL || vnc_display->display == NULL)
Glauber Costa 47b0758
-	term_printf("VNC server disabled\n");
Glauber Costa 47b0758
-    else {
Glauber Costa 47b0758
-	term_printf("VNC server active on: ");
Glauber Costa 47b0758
-	term_print_filename(vnc_display->display);
Glauber Costa 47b0758
-	term_printf("\n");
Glauber Costa 47b0758
-
Glauber Costa 47b0758
-	if (vnc_display->clients == NULL)
Glauber Costa 47b0758
-	    term_printf("No client connected\n");
Glauber Costa 47b0758
-	else
Glauber Costa 47b0758
-	    term_printf("Client connected\n");
Glauber Costa 47b0758
+    if (vnc_display == NULL || vnc_display->display == NULL) {
Glauber Costa 47b0758
+	term_printf("Server: disabled\n");
Glauber Costa 47b0758
+    } else {
Glauber Costa 47b0758
+	char *serverAddr = vnc_socket_local_addr("     address: %s:%s\n",
Glauber Costa 47b0758
+						 vnc_display->lsock);
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+	if (!serverAddr)
Glauber Costa 47b0758
+	    return;
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+	term_puts("Server:\n");
Glauber Costa 47b0758
+	term_puts(serverAddr);
Glauber Costa 47b0758
+	free(serverAddr);
Glauber Costa 47b0758
+	term_printf("        auth: %s\n", vnc_auth_name(vnc_display));
Glauber Costa 47b0758
+
Glauber Costa 47b0758
+	if (vnc_display->clients) {
Glauber Costa 47b0758
+	    VncState *client = vnc_display->clients;
Glauber Costa 47b0758
+	    while (client) {
Glauber Costa 47b0758
+		do_info_vnc_client(client);
Glauber Costa 47b0758
+		client = client->next;
Glauber Costa 47b0758
+	    }
Glauber Costa 47b0758
+	} else {
Glauber Costa 47b0758
+	    term_printf("Client: none\n");
Glauber Costa 47b0758
+	}
Glauber Costa 47b0758
     }
Glauber Costa 47b0758
 }
Glauber Costa 47b0758