updated to new snapshot
This commit is contained in:
parent
4da298fc81
commit
31b341d5bc
@ -1 +1 @@
|
||||
kvm-84.git-snapshot-20090303.tar.gz
|
||||
kvm-84.git-snapshot-20090310.tar.gz
|
||||
|
@ -1,43 +0,0 @@
|
||||
This patch was previously posted here:
|
||||
|
||||
http://lists.gnu.org/archive/html/qemu-devel/2009-02/msg00820.html
|
||||
|
||||
In the case where the TLS handshake does *not* block on I/O, QEMU
|
||||
sends the next 'start sub-auth' message twice. This seriously confuses
|
||||
the VNC client :-) Fortunately the chances of the handshake not blocking
|
||||
are close to zero for a TCP socket, which is why it has not been noticed
|
||||
thus far. Even with both client & server on localhost, I can only hit the
|
||||
bug 1 time in 20.
|
||||
|
||||
NB, the diff context here is not too informative. If you look at the
|
||||
full code you'll see that a few lines early we called vnc_start_tls()
|
||||
which called vnc_continue_handshake() which called the method
|
||||
start_auth_vencrypt_subauth(). Hence, fixing the bug, just involves
|
||||
removing the 2nd bogus call to start_auth_vencrypt_subauth() as per
|
||||
this patch.
|
||||
|
||||
|
||||
vnc.c | 8 --------
|
||||
1 file changed, 8 deletions(-)
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
@@ -2096,14 +2096,6 @@ static int protocol_client_vencrypt_auth
|
||||
VNC_DEBUG("Failed to complete TLS\n");
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
- if (vs->wiremode == VNC_WIREMODE_TLS) {
|
||||
- VNC_DEBUG("Starting VeNCrypt subauth\n");
|
||||
- return start_auth_vencrypt_subauth(vs);
|
||||
- } else {
|
||||
- VNC_DEBUG("TLS handshake blocked\n");
|
||||
- return 0;
|
||||
- }
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,192 +0,0 @@
|
||||
The current 'info vnc' monitor output just displays the VNC server address
|
||||
as provided by the -vnc command line flag. This isn't particularly useful
|
||||
since it doesn't tell you what VNC is actually listening on. eg, if you
|
||||
use '-vnc :1' it is useful to know whether this translated to '0.0.0.0:5901'
|
||||
or chose IPv6 ':::5901'. It is also useful to know the address of the
|
||||
client that is currently connected. It is also useful to know the active
|
||||
authentication (if any).
|
||||
|
||||
This patch tweaks the monitor output to look like:
|
||||
|
||||
(qemu) info vnc
|
||||
Server:
|
||||
address: 0.0.0.0:5902
|
||||
auth: vencrypt+x509
|
||||
Client: none
|
||||
|
||||
And when 2 clients are connected
|
||||
|
||||
(qemu) info vnc
|
||||
Server:
|
||||
address: 0.0.0.0:5902
|
||||
auth: vencrypt+x509
|
||||
Client:
|
||||
address: 10.33.6.67:38621
|
||||
Client:
|
||||
address: 10.33.6.63:38620
|
||||
|
||||
More data will be added to this later in the patch series...
|
||||
|
||||
The 'addr_to_string' helper method in this patch is overly generic
|
||||
for the needs of this patch alone. This is because it will be re-used
|
||||
by the later SASL patches in this series, where the flexibility is
|
||||
important.
|
||||
|
||||
|
||||
vnc.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 127 insertions(+), 10 deletions(-)
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
@@ -166,19 +166,136 @@ struct VncState
|
||||
static VncDisplay *vnc_display; /* needed for info vnc */
|
||||
static DisplayChangeListener *dcl;
|
||||
|
||||
+static char *addr_to_string(const char *format,
|
||||
+ struct sockaddr_storage *sa,
|
||||
+ socklen_t salen) {
|
||||
+ char *addr;
|
||||
+ char host[NI_MAXHOST];
|
||||
+ char serv[NI_MAXSERV];
|
||||
+ int err;
|
||||
+
|
||||
+ if ((err = getnameinfo((struct sockaddr *)sa, salen,
|
||||
+ host, sizeof(host),
|
||||
+ serv, sizeof(serv),
|
||||
+ NI_NUMERICHOST | NI_NUMERICSERV)) != 0) {
|
||||
+ VNC_DEBUG("Cannot resolve address %d: %s\n",
|
||||
+ err, gai_strerror(err));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (asprintf(&addr, format, host, serv) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return addr;
|
||||
+}
|
||||
+
|
||||
+static char *vnc_socket_local_addr(const char *format, int fd) {
|
||||
+ struct sockaddr_storage sa;
|
||||
+ socklen_t salen;
|
||||
+
|
||||
+ salen = sizeof(sa);
|
||||
+ if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return addr_to_string(format, &sa, salen);
|
||||
+}
|
||||
+
|
||||
+static char *vnc_socket_remote_addr(const char *format, int fd) {
|
||||
+ struct sockaddr_storage sa;
|
||||
+ socklen_t salen;
|
||||
+
|
||||
+ salen = sizeof(sa);
|
||||
+ if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return addr_to_string(format, &sa, salen);
|
||||
+}
|
||||
+
|
||||
+static const char *vnc_auth_name(VncDisplay *vd) {
|
||||
+ switch (vd->auth) {
|
||||
+ case VNC_AUTH_INVALID:
|
||||
+ return "invalid";
|
||||
+ case VNC_AUTH_NONE:
|
||||
+ return "none";
|
||||
+ case VNC_AUTH_VNC:
|
||||
+ return "vnc";
|
||||
+ case VNC_AUTH_RA2:
|
||||
+ return "ra2";
|
||||
+ case VNC_AUTH_RA2NE:
|
||||
+ return "ra2ne";
|
||||
+ case VNC_AUTH_TIGHT:
|
||||
+ return "tight";
|
||||
+ case VNC_AUTH_ULTRA:
|
||||
+ return "ultra";
|
||||
+ case VNC_AUTH_TLS:
|
||||
+ return "tls";
|
||||
+ case VNC_AUTH_VENCRYPT:
|
||||
+#ifdef CONFIG_VNC_TLS
|
||||
+ switch (vd->subauth) {
|
||||
+ case VNC_AUTH_VENCRYPT_PLAIN:
|
||||
+ return "vencrypt+plain";
|
||||
+ case VNC_AUTH_VENCRYPT_TLSNONE:
|
||||
+ return "vencrypt+tls+none";
|
||||
+ case VNC_AUTH_VENCRYPT_TLSVNC:
|
||||
+ return "vencrypt+tls+vnc";
|
||||
+ case VNC_AUTH_VENCRYPT_TLSPLAIN:
|
||||
+ return "vencrypt+tls+plain";
|
||||
+ case VNC_AUTH_VENCRYPT_X509NONE:
|
||||
+ return "vencrypt+x509+none";
|
||||
+ case VNC_AUTH_VENCRYPT_X509VNC:
|
||||
+ return "vencrypt+x509+vnc";
|
||||
+ case VNC_AUTH_VENCRYPT_X509PLAIN:
|
||||
+ return "vencrypt+x509+plain";
|
||||
+ default:
|
||||
+ return "vencrypt";
|
||||
+ }
|
||||
+#else
|
||||
+ return "vencrypt";
|
||||
+#endif
|
||||
+ }
|
||||
+ return "unknown";
|
||||
+}
|
||||
+
|
||||
+#define VNC_SOCKET_FORMAT_PRETTY "local %s:%s"
|
||||
+
|
||||
+static void do_info_vnc_client(VncState *client)
|
||||
+{
|
||||
+ char *clientAddr =
|
||||
+ vnc_socket_remote_addr(" address: %s:%s\n",
|
||||
+ client->csock);
|
||||
+ if (!clientAddr)
|
||||
+ return;
|
||||
+
|
||||
+ term_puts("Client:\n");
|
||||
+ term_puts(clientAddr);
|
||||
+ free(clientAddr);
|
||||
+}
|
||||
+
|
||||
void do_info_vnc(void)
|
||||
{
|
||||
- if (vnc_display == NULL || vnc_display->display == NULL)
|
||||
- term_printf("VNC server disabled\n");
|
||||
- else {
|
||||
- term_printf("VNC server active on: ");
|
||||
- term_print_filename(vnc_display->display);
|
||||
- term_printf("\n");
|
||||
-
|
||||
- if (vnc_display->clients == NULL)
|
||||
- term_printf("No client connected\n");
|
||||
- else
|
||||
- term_printf("Client connected\n");
|
||||
+ if (vnc_display == NULL || vnc_display->display == NULL) {
|
||||
+ term_printf("Server: disabled\n");
|
||||
+ } else {
|
||||
+ char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n",
|
||||
+ vnc_display->lsock);
|
||||
+
|
||||
+ if (!serverAddr)
|
||||
+ return;
|
||||
+
|
||||
+ term_puts("Server:\n");
|
||||
+ term_puts(serverAddr);
|
||||
+ free(serverAddr);
|
||||
+ term_printf(" auth: %s\n", vnc_auth_name(vnc_display));
|
||||
+
|
||||
+ if (vnc_display->clients) {
|
||||
+ VncState *client = vnc_display->clients;
|
||||
+ while (client) {
|
||||
+ do_info_vnc_client(client);
|
||||
+ client = client->next;
|
||||
+ }
|
||||
+ } else {
|
||||
+ term_printf("Client: none\n");
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
@ -1,352 +0,0 @@
|
||||
Each of the graphical frontends #include a .c file, for keymap code
|
||||
resulting in duplicated definitions & duplicated compiled code. A
|
||||
couple of small changes allowed this to be sanitized, so instead of
|
||||
doing a #include "keymaps.c", duplicating all code, we can have a
|
||||
shared keymaps.h file, and only compile code once. This allows the
|
||||
next patch to move the VncState struct out into a header file without
|
||||
causing clashing definitions.
|
||||
|
||||
|
||||
Makefile | 9 +++++---
|
||||
b/keymaps.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
curses.c | 3 --
|
||||
curses_keys.h | 9 +++-----
|
||||
keymaps.c | 45 ++++++++++++++++---------------------------
|
||||
sdl.c | 3 --
|
||||
sdl_keysym.h | 7 ++----
|
||||
vnc.c | 5 +---
|
||||
vnc_keysym.h | 7 ++----
|
||||
9 files changed, 97 insertions(+), 51 deletions(-)
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/Makefile
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/Makefile
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/Makefile
|
||||
@@ -141,6 +141,7 @@ endif
|
||||
AUDIO_OBJS+= wavcapture.o
|
||||
OBJS+=$(addprefix audio/, $(AUDIO_OBJS))
|
||||
|
||||
+OBJS+=keymaps.o
|
||||
ifdef CONFIG_SDL
|
||||
OBJS+=sdl.o x_keymap.o
|
||||
endif
|
||||
@@ -165,15 +166,17 @@ LIBS+=$(VDE_LIBS)
|
||||
|
||||
cocoa.o: cocoa.m
|
||||
|
||||
-sdl.o: sdl.c keymaps.c sdl_keysym.h
|
||||
+keymaps.o: keymaps.c keymaps.h
|
||||
+
|
||||
+sdl.o: sdl.c keymaps.h sdl_keysym.h
|
||||
|
||||
sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
|
||||
|
||||
-vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h d3des.c d3des.h
|
||||
+vnc.o: vnc.c keymaps.h sdl_keysym.h vnchextile.h d3des.c d3des.h
|
||||
|
||||
vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
|
||||
|
||||
-curses.o: curses.c keymaps.c curses_keys.h
|
||||
+curses.o: curses.c keymaps.h curses_keys.h
|
||||
|
||||
bt-host.o: CFLAGS += $(CONFIG_BLUEZ_CFLAGS)
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/curses.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/curses.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/curses.c
|
||||
@@ -158,7 +158,6 @@ static void curses_cursor_position(Displ
|
||||
/* generic keyboard conversion */
|
||||
|
||||
#include "curses_keys.h"
|
||||
-#include "keymaps.c"
|
||||
|
||||
static kbd_layout_t *kbd_layout = 0;
|
||||
static int keycode2keysym[CURSES_KEYS];
|
||||
@@ -311,7 +310,7 @@ static void curses_keyboard_setup(void)
|
||||
keyboard_layout = "en-us";
|
||||
#endif
|
||||
if(keyboard_layout) {
|
||||
- kbd_layout = init_keyboard_layout(keyboard_layout);
|
||||
+ kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
|
||||
if (!kbd_layout)
|
||||
exit(1);
|
||||
}
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/curses_keys.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/curses_keys.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/curses_keys.h
|
||||
@@ -21,6 +21,10 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
+
|
||||
+#include "keymaps.h"
|
||||
+
|
||||
+
|
||||
#define KEY_RELEASE 0x80
|
||||
#define KEY_MASK 0x7f
|
||||
#define SHIFT_CODE 0x2a
|
||||
@@ -239,11 +243,6 @@ static const int curses2keysym[CURSES_KE
|
||||
|
||||
};
|
||||
|
||||
-typedef struct {
|
||||
- const char* name;
|
||||
- int keysym;
|
||||
-} name2keysym_t;
|
||||
-
|
||||
static const name2keysym_t name2keysym[] = {
|
||||
/* Plain ASCII */
|
||||
{ "space", 0x020 },
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/keymaps.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/keymaps.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/keymaps.c
|
||||
@@ -22,34 +22,20 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
-static int get_keysym(const char *name)
|
||||
+#include "keymaps.h"
|
||||
+#include "sysemu.h"
|
||||
+
|
||||
+static int get_keysym(const name2keysym_t *table,
|
||||
+ const char *name)
|
||||
{
|
||||
const name2keysym_t *p;
|
||||
- for(p = name2keysym; p->name != NULL; p++) {
|
||||
+ for(p = table; p->name != NULL; p++) {
|
||||
if (!strcmp(p->name, name))
|
||||
return p->keysym;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
-struct key_range {
|
||||
- int start;
|
||||
- int end;
|
||||
- struct key_range *next;
|
||||
-};
|
||||
-
|
||||
-#define MAX_NORMAL_KEYCODE 512
|
||||
-#define MAX_EXTRA_COUNT 256
|
||||
-typedef struct {
|
||||
- uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
|
||||
- struct {
|
||||
- int keysym;
|
||||
- uint16_t keycode;
|
||||
- } keysym2keycode_extra[MAX_EXTRA_COUNT];
|
||||
- int extra_count;
|
||||
- struct key_range *keypad_range;
|
||||
- struct key_range *numlock_range;
|
||||
-} kbd_layout_t;
|
||||
|
||||
static void add_to_key_range(struct key_range **krp, int code) {
|
||||
struct key_range *kr;
|
||||
@@ -73,7 +59,8 @@ static void add_to_key_range(struct key_
|
||||
}
|
||||
}
|
||||
|
||||
-static kbd_layout_t *parse_keyboard_layout(const char *language,
|
||||
+static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
|
||||
+ const char *language,
|
||||
kbd_layout_t * k)
|
||||
{
|
||||
FILE *f;
|
||||
@@ -102,7 +89,7 @@ static kbd_layout_t *parse_keyboard_layo
|
||||
if (!strncmp(line, "map ", 4))
|
||||
continue;
|
||||
if (!strncmp(line, "include ", 8)) {
|
||||
- parse_keyboard_layout(line + 8, k);
|
||||
+ parse_keyboard_layout(table, line + 8, k);
|
||||
} else {
|
||||
char *end_of_keysym = line;
|
||||
while (*end_of_keysym != 0 && *end_of_keysym != ' ')
|
||||
@@ -110,7 +97,7 @@ static kbd_layout_t *parse_keyboard_layo
|
||||
if (*end_of_keysym) {
|
||||
int keysym;
|
||||
*end_of_keysym = 0;
|
||||
- keysym = get_keysym(line);
|
||||
+ keysym = get_keysym(table, line);
|
||||
if (keysym == 0) {
|
||||
// fprintf(stderr, "Warning: unknown keysym %s\n", line);
|
||||
} else {
|
||||
@@ -154,12 +141,14 @@ static kbd_layout_t *parse_keyboard_layo
|
||||
return k;
|
||||
}
|
||||
|
||||
-static void *init_keyboard_layout(const char *language)
|
||||
+
|
||||
+void *init_keyboard_layout(const name2keysym_t *table, const char *language)
|
||||
{
|
||||
- return parse_keyboard_layout(language, 0);
|
||||
+ return parse_keyboard_layout(table, language, 0);
|
||||
}
|
||||
|
||||
-static int keysym2scancode(void *kbd_layout, int keysym)
|
||||
+
|
||||
+int keysym2scancode(void *kbd_layout, int keysym)
|
||||
{
|
||||
kbd_layout_t *k = kbd_layout;
|
||||
if (keysym < MAX_NORMAL_KEYCODE) {
|
||||
@@ -180,7 +169,7 @@ static int keysym2scancode(void *kbd_lay
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int keycode_is_keypad(void *kbd_layout, int keycode)
|
||||
+int keycode_is_keypad(void *kbd_layout, int keycode)
|
||||
{
|
||||
kbd_layout_t *k = kbd_layout;
|
||||
struct key_range *kr;
|
||||
@@ -191,7 +180,7 @@ static inline int keycode_is_keypad(void
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static inline int keysym_is_numlock(void *kbd_layout, int keysym)
|
||||
+int keysym_is_numlock(void *kbd_layout, int keysym)
|
||||
{
|
||||
kbd_layout_t *k = kbd_layout;
|
||||
struct key_range *kr;
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/keymaps.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/keymaps.h
|
||||
@@ -0,0 +1,60 @@
|
||||
+/*
|
||||
+ * QEMU keysym to keycode conversion using rdesktop keymaps
|
||||
+ *
|
||||
+ * Copyright (c) 2004 Johannes Schindelin
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
+ * THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __QEMU_KEYMAPS_H__
|
||||
+#define __QEMU_KEYMAPS_H__
|
||||
+
|
||||
+#include "qemu-common.h"
|
||||
+
|
||||
+typedef struct {
|
||||
+ const char* name;
|
||||
+ int keysym;
|
||||
+} name2keysym_t;
|
||||
+
|
||||
+struct key_range {
|
||||
+ int start;
|
||||
+ int end;
|
||||
+ struct key_range *next;
|
||||
+};
|
||||
+
|
||||
+#define MAX_NORMAL_KEYCODE 512
|
||||
+#define MAX_EXTRA_COUNT 256
|
||||
+typedef struct {
|
||||
+ uint16_t keysym2keycode[MAX_NORMAL_KEYCODE];
|
||||
+ struct {
|
||||
+ int keysym;
|
||||
+ uint16_t keycode;
|
||||
+ } keysym2keycode_extra[MAX_EXTRA_COUNT];
|
||||
+ int extra_count;
|
||||
+ struct key_range *keypad_range;
|
||||
+ struct key_range *numlock_range;
|
||||
+} kbd_layout_t;
|
||||
+
|
||||
+
|
||||
+void *init_keyboard_layout(const name2keysym_t *table, const char *language);
|
||||
+int keysym2scancode(void *kbd_layout, int keysym);
|
||||
+int keycode_is_keypad(void *kbd_layout, int keycode);
|
||||
+int keysym_is_numlock(void *kbd_layout, int keysym);
|
||||
+
|
||||
+#endif /* __QEMU_KEYMAPS_H__ */
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/sdl.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/sdl.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/sdl.c
|
||||
@@ -107,7 +107,6 @@ static void sdl_resize(DisplayState *ds)
|
||||
/* generic keyboard conversion */
|
||||
|
||||
#include "sdl_keysym.h"
|
||||
-#include "keymaps.c"
|
||||
|
||||
static kbd_layout_t *kbd_layout = NULL;
|
||||
|
||||
@@ -623,7 +622,7 @@ void sdl_display_init(DisplayState *ds,
|
||||
keyboard_layout = "en-us";
|
||||
#endif
|
||||
if(keyboard_layout) {
|
||||
- kbd_layout = init_keyboard_layout(keyboard_layout);
|
||||
+ kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
|
||||
if (!kbd_layout)
|
||||
exit(1);
|
||||
}
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/sdl_keysym.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/sdl_keysym.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/sdl_keysym.h
|
||||
@@ -1,7 +1,6 @@
|
||||
-typedef struct {
|
||||
- const char* name;
|
||||
- int keysym;
|
||||
-} name2keysym_t;
|
||||
+
|
||||
+#include "keymaps.h"
|
||||
+
|
||||
static const name2keysym_t name2keysym[]={
|
||||
/* ascii */
|
||||
{ "space", 0x020},
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "vnc.h"
|
||||
#include "vnc_keysym.h"
|
||||
-#include "keymaps.c"
|
||||
#include "d3des.h"
|
||||
|
||||
#ifdef CONFIG_VNC_TLS
|
||||
@@ -2420,9 +2419,9 @@ void vnc_display_init(DisplayState *ds)
|
||||
vs->ds = ds;
|
||||
|
||||
if (keyboard_layout)
|
||||
- vs->kbd_layout = init_keyboard_layout(keyboard_layout);
|
||||
+ vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
|
||||
else
|
||||
- vs->kbd_layout = init_keyboard_layout("en-us");
|
||||
+ vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
|
||||
|
||||
if (!vs->kbd_layout)
|
||||
exit(1);
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc_keysym.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc_keysym.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc_keysym.h
|
||||
@@ -1,7 +1,6 @@
|
||||
-typedef struct {
|
||||
- const char* name;
|
||||
- int keysym;
|
||||
-} name2keysym_t;
|
||||
+
|
||||
+#include "keymaps.h"
|
||||
+
|
||||
static const name2keysym_t name2keysym[]={
|
||||
/* ascii */
|
||||
{ "space", 0x020},
|
@ -1,315 +0,0 @@
|
||||
This patch moves the definitions of VncState and VncDisplay structs
|
||||
out into a vnc.h header file. This is to allow the code for TLS
|
||||
and SASL auth mechanisms to be moved out of the main vnc.c file.
|
||||
|
||||
|
||||
vnc.c | 109 ------------------------------------------------
|
||||
vnc.h | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
2 files changed, 148 insertions(+), 110 deletions(-)
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
@@ -3,6 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
|
||||
* Copyright (C) 2006 Fabrice Bellard
|
||||
+ * Copyright (C) 2009 Red Hat, Inc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,25 +24,16 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
-#include "qemu-common.h"
|
||||
-#include "console.h"
|
||||
+#include "vnc.h"
|
||||
#include "sysemu.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "qemu-timer.h"
|
||||
-#include "audio/audio.h"
|
||||
-#include <zlib.h>
|
||||
|
||||
#define VNC_REFRESH_INTERVAL (1000 / 30)
|
||||
|
||||
-#include "vnc.h"
|
||||
#include "vnc_keysym.h"
|
||||
#include "d3des.h"
|
||||
|
||||
-#ifdef CONFIG_VNC_TLS
|
||||
-#include <gnutls/gnutls.h>
|
||||
-#include <gnutls/x509.h>
|
||||
-#endif /* CONFIG_VNC_TLS */
|
||||
-
|
||||
// #define _VNC_DEBUG 1
|
||||
|
||||
#ifdef _VNC_DEBUG
|
||||
@@ -64,103 +56,6 @@ static void vnc_debug_gnutls_log(int lev
|
||||
} \
|
||||
}
|
||||
|
||||
-typedef struct Buffer
|
||||
-{
|
||||
- size_t capacity;
|
||||
- size_t offset;
|
||||
- uint8_t *buffer;
|
||||
-} Buffer;
|
||||
-
|
||||
-typedef struct VncState VncState;
|
||||
-
|
||||
-typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
|
||||
-
|
||||
-typedef void VncWritePixels(VncState *vs, void *data, int size);
|
||||
-
|
||||
-typedef void VncSendHextileTile(VncState *vs,
|
||||
- int x, int y, int w, int h,
|
||||
- void *last_bg,
|
||||
- void *last_fg,
|
||||
- int *has_bg, int *has_fg);
|
||||
-
|
||||
-#define VNC_MAX_WIDTH 2048
|
||||
-#define VNC_MAX_HEIGHT 2048
|
||||
-#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
|
||||
-
|
||||
-#define VNC_AUTH_CHALLENGE_SIZE 16
|
||||
-
|
||||
-typedef struct VncDisplay VncDisplay;
|
||||
-
|
||||
-struct VncDisplay
|
||||
-{
|
||||
- int lsock;
|
||||
- DisplayState *ds;
|
||||
- VncState *clients;
|
||||
- kbd_layout_t *kbd_layout;
|
||||
-
|
||||
- char *display;
|
||||
- char *password;
|
||||
- int auth;
|
||||
-#ifdef CONFIG_VNC_TLS
|
||||
- int subauth;
|
||||
- int x509verify;
|
||||
-
|
||||
- char *x509cacert;
|
||||
- char *x509cacrl;
|
||||
- char *x509cert;
|
||||
- char *x509key;
|
||||
-#endif
|
||||
-};
|
||||
-
|
||||
-struct VncState
|
||||
-{
|
||||
- QEMUTimer *timer;
|
||||
- int csock;
|
||||
- DisplayState *ds;
|
||||
- VncDisplay *vd;
|
||||
- int need_update;
|
||||
- uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
|
||||
- char *old_data;
|
||||
- uint32_t features;
|
||||
- int absolute;
|
||||
- int last_x;
|
||||
- int last_y;
|
||||
-
|
||||
- uint32_t vnc_encoding;
|
||||
- uint8_t tight_quality;
|
||||
- uint8_t tight_compression;
|
||||
-
|
||||
- int major;
|
||||
- int minor;
|
||||
-
|
||||
- char challenge[VNC_AUTH_CHALLENGE_SIZE];
|
||||
-
|
||||
-#ifdef CONFIG_VNC_TLS
|
||||
- int wiremode;
|
||||
- gnutls_session_t tls_session;
|
||||
-#endif
|
||||
-
|
||||
- Buffer output;
|
||||
- Buffer input;
|
||||
- /* current output mode information */
|
||||
- VncWritePixels *write_pixels;
|
||||
- VncSendHextileTile *send_hextile_tile;
|
||||
- DisplaySurface clientds, serverds;
|
||||
-
|
||||
- CaptureVoiceOut *audio_cap;
|
||||
- struct audsettings as;
|
||||
-
|
||||
- VncReadEvent *read_handler;
|
||||
- size_t read_handler_expect;
|
||||
- /* input */
|
||||
- uint8_t modifiers_state[256];
|
||||
-
|
||||
- Buffer zlib;
|
||||
- Buffer zlib_tmp;
|
||||
- z_stream zlib_stream[4];
|
||||
-
|
||||
- VncState *next;
|
||||
-};
|
||||
|
||||
static VncDisplay *vnc_display; /* needed for info vnc */
|
||||
static DisplayChangeListener *dcl;
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.h
|
||||
@@ -1,5 +1,148 @@
|
||||
-#ifndef __VNCTIGHT_H
|
||||
-#define __VNCTIGHT_H
|
||||
+/*
|
||||
+ * QEMU VNC display driver
|
||||
+ *
|
||||
+ * Copyright (C) 2006 Anthony Liguori <anthony@codemonkey.ws>
|
||||
+ * Copyright (C) 2006 Fabrice Bellard
|
||||
+ * Copyright (C) 2009 Red Hat, Inc
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
+ * THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __QEMU_VNC_H
|
||||
+#define __QEMU_VNC_H
|
||||
+
|
||||
+#include "qemu-common.h"
|
||||
+#include "console.h"
|
||||
+#include "audio/audio.h"
|
||||
+#include <zlib.h>
|
||||
+
|
||||
+#ifdef CONFIG_VNC_TLS
|
||||
+#include <gnutls/gnutls.h>
|
||||
+#include <gnutls/x509.h>
|
||||
+#endif /* CONFIG_VNC_TLS */
|
||||
+
|
||||
+#include "keymaps.h"
|
||||
+
|
||||
+/*****************************************************************************
|
||||
+ *
|
||||
+ * Core data structures
|
||||
+ *
|
||||
+ *****************************************************************************/
|
||||
+
|
||||
+typedef struct Buffer
|
||||
+{
|
||||
+ size_t capacity;
|
||||
+ size_t offset;
|
||||
+ uint8_t *buffer;
|
||||
+} Buffer;
|
||||
+
|
||||
+typedef struct VncState VncState;
|
||||
+
|
||||
+typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
|
||||
+
|
||||
+typedef void VncWritePixels(VncState *vs, void *data, int size);
|
||||
+
|
||||
+typedef void VncSendHextileTile(VncState *vs,
|
||||
+ int x, int y, int w, int h,
|
||||
+ void *last_bg,
|
||||
+ void *last_fg,
|
||||
+ int *has_bg, int *has_fg);
|
||||
+
|
||||
+#define VNC_MAX_WIDTH 2048
|
||||
+#define VNC_MAX_HEIGHT 2048
|
||||
+#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
|
||||
+
|
||||
+#define VNC_AUTH_CHALLENGE_SIZE 16
|
||||
+
|
||||
+typedef struct VncDisplay VncDisplay;
|
||||
+
|
||||
+struct VncDisplay
|
||||
+{
|
||||
+ int lsock;
|
||||
+ DisplayState *ds;
|
||||
+ VncState *clients;
|
||||
+ kbd_layout_t *kbd_layout;
|
||||
+
|
||||
+ char *display;
|
||||
+ char *password;
|
||||
+ int auth;
|
||||
+#ifdef CONFIG_VNC_TLS
|
||||
+ int subauth;
|
||||
+ int x509verify;
|
||||
+
|
||||
+ char *x509cacert;
|
||||
+ char *x509cacrl;
|
||||
+ char *x509cert;
|
||||
+ char *x509key;
|
||||
+#endif
|
||||
+};
|
||||
+
|
||||
+struct VncState
|
||||
+{
|
||||
+ QEMUTimer *timer;
|
||||
+ int csock;
|
||||
+ DisplayState *ds;
|
||||
+ VncDisplay *vd;
|
||||
+ int need_update;
|
||||
+ uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
|
||||
+ char *old_data;
|
||||
+ uint32_t features;
|
||||
+ int absolute;
|
||||
+ int last_x;
|
||||
+ int last_y;
|
||||
+
|
||||
+ uint32_t vnc_encoding;
|
||||
+ uint8_t tight_quality;
|
||||
+ uint8_t tight_compression;
|
||||
+
|
||||
+ int major;
|
||||
+ int minor;
|
||||
+
|
||||
+ char challenge[VNC_AUTH_CHALLENGE_SIZE];
|
||||
+
|
||||
+#ifdef CONFIG_VNC_TLS
|
||||
+ int wiremode;
|
||||
+ gnutls_session_t tls_session;
|
||||
+#endif
|
||||
+
|
||||
+ Buffer output;
|
||||
+ Buffer input;
|
||||
+ /* current output mode information */
|
||||
+ VncWritePixels *write_pixels;
|
||||
+ VncSendHextileTile *send_hextile_tile;
|
||||
+ DisplaySurface clientds, serverds;
|
||||
+
|
||||
+ CaptureVoiceOut *audio_cap;
|
||||
+ struct audsettings as;
|
||||
+
|
||||
+ VncReadEvent *read_handler;
|
||||
+ size_t read_handler_expect;
|
||||
+ /* input */
|
||||
+ uint8_t modifiers_state[256];
|
||||
+
|
||||
+ Buffer zlib;
|
||||
+ Buffer zlib_tmp;
|
||||
+ z_stream zlib_stream[4];
|
||||
+
|
||||
+ VncState *next;
|
||||
+};
|
||||
+
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
@@ -111,4 +254,4 @@ enum {
|
||||
#define VNC_FEATURE_ZLIB_MASK (1 << VNC_FEATURE_ZLIB)
|
||||
#define VNC_FEATURE_COPYRECT_MASK (1 << VNC_FEATURE_COPYRECT)
|
||||
|
||||
-#endif /* __VNCTIGHT_H */
|
||||
+#endif /* __QEMU_VNC_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,124 +0,0 @@
|
||||
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
|
||||
|
||||
|
||||
|
||||
vnc-tls.c | 17 +++++++++++++++++
|
||||
vnc-tls.h | 3 +++
|
||||
vnc.c | 19 +++++++++++++++++--
|
||||
3 files changed, 37 insertions(+), 2 deletions(-)
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
|
||||
@@ -241,6 +241,22 @@ int vnc_tls_validate_certificate(struct
|
||||
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 VncSt
|
||||
vs->tls.session = NULL;
|
||||
}
|
||||
vs->tls.wiremode = VNC_WIREMODE_CLEAR;
|
||||
+ free(vs->tls.dname);
|
||||
}
|
||||
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/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);
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
@@ -156,6 +156,21 @@ static void do_info_vnc_client(VncState
|
||||
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)
|
||||
@@ -1823,7 +1838,7 @@ static int protocol_client_auth(VncState
|
||||
/* 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";
|
||||
@@ -1863,7 +1878,7 @@ static int protocol_client_auth(VncState
|
||||
#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";
|
@ -1,781 +0,0 @@
|
||||
This patch introduces a generic internal API for access control lists
|
||||
to be used by network servers in QEMU. It adds support for checking
|
||||
these ACL in the VNC server, in two places. The first ACL is for the
|
||||
SASL authentication mechanism, checking the SASL username. This ACL
|
||||
is called 'vnc.username'. The second is for the TLS authentication
|
||||
mechanism, when x509 client certificates are turned on, checking against
|
||||
the Distinguished Name of the client. This ACL is called 'vnc.x509dname'
|
||||
|
||||
The internal API provides for an ACL with the following characteristics
|
||||
|
||||
- A unique name, eg vnc.username, and vnc.x509dname.
|
||||
- A default policy, allow or deny
|
||||
- An ordered series of match rules, with allow or deny policy
|
||||
|
||||
If none of the match rules apply, then the default policy is
|
||||
used.
|
||||
|
||||
There is a monitor API to manipulate the ACLs, which I'll describe via
|
||||
examples
|
||||
|
||||
(qemu) acl show vnc.username
|
||||
policy: allow
|
||||
(qemu) acl policy vnc.username denya
|
||||
acl: policy set to 'deny'
|
||||
(qemu) acl allow vnc.username fred
|
||||
acl: added rule at position 1
|
||||
(qemu) acl allow vnc.username bob
|
||||
acl: added rule at position 2
|
||||
(qemu) acl allow vnc.username joe 1
|
||||
acl: added rule at position 1
|
||||
(qemu) acl show vnc.username
|
||||
policy: deny
|
||||
0: allow fred
|
||||
1: allow joe
|
||||
2: allow bob
|
||||
|
||||
|
||||
(qemu) acl show vnc.x509dname
|
||||
policy: allow
|
||||
(qemu) acl policy vnc.x509dname deny
|
||||
acl: policy set to 'deny'
|
||||
(qemu) acl allow vnc.x509dname C=GB,O=ACME,L=London,CN=*
|
||||
acl: added rule at position 1
|
||||
(qemu) acl allow vnc.x509dname C=GB,O=ACME,L=Boston,CN=bob
|
||||
acl: added rule at position 2
|
||||
(qemu) acl show vnc.x509dname
|
||||
policy: deny
|
||||
0: allow C=GB,O=ACME,L=London,CN=*
|
||||
1: allow C=GB,O=ACME,L=Boston,CN=bob
|
||||
|
||||
By default the VNC server will not use any ACLs, allowing access to
|
||||
the server if the user successfully authenticates. To enable use of
|
||||
ACLs to restrict user access, the ',acl' flag should be given when
|
||||
starting QEMU. The initial ACL activated will be a 'deny all' policy
|
||||
and should be customized using monitor commands.
|
||||
|
||||
eg enable SASL auth and ACLs
|
||||
|
||||
qemu .... -vnc localhost:1,sasl,acl
|
||||
|
||||
The next patch will provide a way to load a pre-defined ACL when
|
||||
starting up
|
||||
|
||||
|
||||
Makefile | 6 +
|
||||
b/acl.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
b/acl.h | 74 ++++++++++++++++++++++
|
||||
configure | 18 +++++
|
||||
monitor.c | 95 ++++++++++++++++++++++++++++
|
||||
qemu-doc.texi | 49 ++++++++++++++
|
||||
vnc-auth-sasl.c | 16 +++-
|
||||
vnc-auth-sasl.h | 7 ++
|
||||
vnc-tls.c | 19 +++++
|
||||
vnc-tls.h | 3
|
||||
vnc.c | 21 ++++++
|
||||
vnc.h | 3
|
||||
12 files changed, 491 insertions(+), 5 deletions(-)
|
||||
|
||||
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/Makefile
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/Makefile
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/Makefile
|
||||
@@ -148,7 +148,7 @@ endif
|
||||
ifdef CONFIG_CURSES
|
||||
OBJS+=curses.o
|
||||
endif
|
||||
-OBJS+=vnc.o d3des.o
|
||||
+OBJS+=vnc.o acl.o d3des.o
|
||||
ifdef CONFIG_VNC_TLS
|
||||
OBJS+=vnc-tls.o vnc-auth-vencrypt.o
|
||||
endif
|
||||
@@ -178,9 +178,11 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h
|
||||
|
||||
sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
|
||||
|
||||
+acl.o: acl.h acl.c
|
||||
+
|
||||
vnc.h: vnc-tls.h vnc-auth-vencrypt.h vnc-auth-sasl.h keymaps.h
|
||||
|
||||
-vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h
|
||||
+vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h acl.h
|
||||
|
||||
vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/acl.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/acl.c
|
||||
@@ -0,0 +1,185 @@
|
||||
+/*
|
||||
+ * QEMU access control list management
|
||||
+ *
|
||||
+ * Copyright (C) 2009 Red Hat, Inc
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
+ * THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+#include "qemu-common.h"
|
||||
+#include "sysemu.h"
|
||||
+#include "acl.h"
|
||||
+
|
||||
+#ifdef HAVE_FNMATCH_H
|
||||
+#include <fnmatch.h>
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
+static unsigned int nacls = 0;
|
||||
+static qemu_acl **acls = NULL;
|
||||
+
|
||||
+
|
||||
+
|
||||
+qemu_acl *qemu_acl_find(const char *aclname)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0 ; i < nacls ; i++) {
|
||||
+ if (strcmp(acls[i]->aclname, aclname) == 0)
|
||||
+ return acls[i];
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+qemu_acl *qemu_acl_init(const char *aclname)
|
||||
+{
|
||||
+ qemu_acl *acl;
|
||||
+
|
||||
+ acl = qemu_acl_find(aclname);
|
||||
+ if (acl)
|
||||
+ return acl;
|
||||
+
|
||||
+ acl = qemu_malloc(sizeof(*acl));
|
||||
+ acl->aclname = qemu_strdup(aclname);
|
||||
+ /* Deny by default, so there is no window of "open
|
||||
+ * access" between QEMU starting, and the user setting
|
||||
+ * up ACLs in the monitor */
|
||||
+ acl->defaultDeny = 1;
|
||||
+
|
||||
+ acl->nentries = 0;
|
||||
+ TAILQ_INIT(&acl->entries);
|
||||
+
|
||||
+ acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1));
|
||||
+ acls[nacls] = acl;
|
||||
+ nacls++;
|
||||
+
|
||||
+ return acl;
|
||||
+}
|
||||
+
|
||||
+int qemu_acl_party_is_allowed(qemu_acl *acl,
|
||||
+ const char *party)
|
||||
+{
|
||||
+ qemu_acl_entry *entry;
|
||||
+
|
||||
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
||||
+#ifdef HAVE_FNMATCH_H
|
||||
+ if (fnmatch(entry->match, party, 0) == 0)
|
||||
+ return entry->deny ? 0 : 1;
|
||||
+#else
|
||||
+ /* No fnmatch, so fallback to exact string matching
|
||||
+ * instead of allowing wildcards */
|
||||
+ if (strcmp(entry->match, party) == 0)
|
||||
+ return entry->deny ? 0 : 1;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ return acl->defaultDeny ? 0 : 1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void qemu_acl_reset(qemu_acl *acl)
|
||||
+{
|
||||
+ qemu_acl_entry *entry;
|
||||
+
|
||||
+ /* Put back to deny by default, so there is no window
|
||||
+ * of "open access" while the user re-initializes the
|
||||
+ * access control list */
|
||||
+ acl->defaultDeny = 1;
|
||||
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
||||
+ TAILQ_REMOVE(&acl->entries, entry, next);
|
||||
+ free(entry->match);
|
||||
+ free(entry);
|
||||
+ }
|
||||
+ acl->nentries = 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int qemu_acl_append(qemu_acl *acl,
|
||||
+ int deny,
|
||||
+ const char *match)
|
||||
+{
|
||||
+ qemu_acl_entry *entry;
|
||||
+
|
||||
+ entry = qemu_malloc(sizeof(*entry));
|
||||
+ entry->match = qemu_strdup(match);
|
||||
+ entry->deny = deny;
|
||||
+
|
||||
+ TAILQ_INSERT_TAIL(&acl->entries, entry, next);
|
||||
+ acl->nentries++;
|
||||
+
|
||||
+ return acl->nentries;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int qemu_acl_insert(qemu_acl *acl,
|
||||
+ int deny,
|
||||
+ const char *match,
|
||||
+ int index)
|
||||
+{
|
||||
+ qemu_acl_entry *entry;
|
||||
+ qemu_acl_entry *tmp;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ if (index <= 0)
|
||||
+ return -1;
|
||||
+ if (index >= acl->nentries)
|
||||
+ return qemu_acl_append(acl, deny, match);
|
||||
+
|
||||
+
|
||||
+ entry = qemu_malloc(sizeof(*entry));
|
||||
+ entry->match = qemu_strdup(match);
|
||||
+ entry->deny = deny;
|
||||
+
|
||||
+ TAILQ_FOREACH(tmp, &acl->entries, next) {
|
||||
+ i++;
|
||||
+ if (i == index) {
|
||||
+ TAILQ_INSERT_BEFORE(tmp, entry, next);
|
||||
+ acl->nentries++;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+int qemu_acl_remove(qemu_acl *acl,
|
||||
+ const char *match)
|
||||
+{
|
||||
+ qemu_acl_entry *entry;
|
||||
+ int i = 0;
|
||||
+
|
||||
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
||||
+ i++;
|
||||
+ if (strcmp(entry->match, match) == 0) {
|
||||
+ TAILQ_REMOVE(&acl->entries, entry, next);
|
||||
+ return i;
|
||||
+ }
|
||||
+ }
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * c-indent-level: 4
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 8
|
||||
+ * End:
|
||||
+ */
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/acl.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/acl.h
|
||||
@@ -0,0 +1,74 @@
|
||||
+/*
|
||||
+ * QEMU access control list management
|
||||
+ *
|
||||
+ * Copyright (C) 2009 Red Hat, Inc
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ * of this software and associated documentation files (the "Software"), to deal
|
||||
+ * in the Software without restriction, including without limitation the rights
|
||||
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ * copies of the Software, and to permit persons to whom the Software is
|
||||
+ * furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be included in
|
||||
+ * all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
+ * THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __QEMU_ACL_H__
|
||||
+#define __QEMU_ACL_H__
|
||||
+
|
||||
+#include "sys-queue.h"
|
||||
+
|
||||
+typedef struct qemu_acl_entry qemu_acl_entry;
|
||||
+typedef struct qemu_acl qemu_acl;
|
||||
+
|
||||
+struct qemu_acl_entry {
|
||||
+ char *match;
|
||||
+ int deny;
|
||||
+
|
||||
+ TAILQ_ENTRY(qemu_acl_entry) next;
|
||||
+};
|
||||
+
|
||||
+struct qemu_acl {
|
||||
+ char *aclname;
|
||||
+ unsigned int nentries;
|
||||
+ TAILQ_HEAD(,qemu_acl_entry) entries;
|
||||
+ int defaultDeny;
|
||||
+};
|
||||
+
|
||||
+qemu_acl *qemu_acl_init(const char *aclname);
|
||||
+
|
||||
+qemu_acl *qemu_acl_find(const char *aclname);
|
||||
+
|
||||
+int qemu_acl_party_is_allowed(qemu_acl *acl,
|
||||
+ const char *party);
|
||||
+
|
||||
+void qemu_acl_reset(qemu_acl *acl);
|
||||
+
|
||||
+int qemu_acl_append(qemu_acl *acl,
|
||||
+ int deny,
|
||||
+ const char *match);
|
||||
+int qemu_acl_insert(qemu_acl *acl,
|
||||
+ int deny,
|
||||
+ const char *match,
|
||||
+ int index);
|
||||
+int qemu_acl_remove(qemu_acl *acl,
|
||||
+ const char *match);
|
||||
+
|
||||
+#endif /* __QEMU_ACL_H__ */
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * c-indent-level: 4
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 8
|
||||
+ * End:
|
||||
+ */
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/configure
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/configure
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/configure
|
||||
@@ -897,6 +897,21 @@ EOF
|
||||
fi
|
||||
|
||||
##########################################
|
||||
+# fnmatch() probe, used for ACL routines
|
||||
+fnmatch="no"
|
||||
+cat > $TMPC << EOF
|
||||
+#include <fnmatch.h>
|
||||
+int main(void)
|
||||
+{
|
||||
+ fnmatch("foo", "foo", 0);
|
||||
+ return 0;
|
||||
+}
|
||||
+EOF
|
||||
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
|
||||
+ fnmatch="yes"
|
||||
+fi
|
||||
+
|
||||
+##########################################
|
||||
# vde libraries probe
|
||||
if test "$vde" = "yes" ; then
|
||||
cat > $TMPC << EOF
|
||||
@@ -1485,6 +1500,9 @@ if test "$vnc_sasl" = "yes" ; then
|
||||
echo "CONFIG_VNC_SASL_LIBS=$vnc_sasl_libs" >> $config_mak
|
||||
echo "#define CONFIG_VNC_SASL 1" >> $config_h
|
||||
fi
|
||||
+if test "$fnmatch" = "yes" ; then
|
||||
+ echo "#define HAVE_FNMATCH_H 1" >> $config_h
|
||||
+fi
|
||||
qemu_version=`head $source_path/VERSION`
|
||||
echo "VERSION=$qemu_version" >>$config_mak
|
||||
echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/monitor.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/monitor.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/monitor.c
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "qemu-timer.h"
|
||||
#include "migration.h"
|
||||
#include "kvm.h"
|
||||
+#include "acl.h"
|
||||
|
||||
#include "qemu-kvm.h"
|
||||
|
||||
@@ -1452,6 +1453,85 @@ static void do_info_balloon(void)
|
||||
term_printf("balloon: actual=%d\n", (int)(actual >> 20));
|
||||
}
|
||||
|
||||
+static void do_acl(const char *command,
|
||||
+ const char *aclname,
|
||||
+ const char *match,
|
||||
+ int has_index,
|
||||
+ int index)
|
||||
+{
|
||||
+ qemu_acl *acl;
|
||||
+
|
||||
+ acl = qemu_acl_find(aclname);
|
||||
+ if (!acl) {
|
||||
+ term_printf("acl: unknown list '%s'\n", aclname);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp(command, "show") == 0) {
|
||||
+ int i = 0;
|
||||
+ qemu_acl_entry *entry;
|
||||
+ term_printf("policy: %s\n",
|
||||
+ acl->defaultDeny ? "deny" : "allow");
|
||||
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
||||
+ i++;
|
||||
+ term_printf("%d: %s %s\n", i,
|
||||
+ entry->deny ? "deny" : "allow",
|
||||
+ entry->match);
|
||||
+ }
|
||||
+ } else if (strcmp(command, "reset") == 0) {
|
||||
+ qemu_acl_reset(acl);
|
||||
+ term_printf("acl: removed all rules\n");
|
||||
+ } else if (strcmp(command, "policy") == 0) {
|
||||
+ if (!match) {
|
||||
+ term_printf("acl: missing policy parameter\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp(match, "allow") == 0) {
|
||||
+ acl->defaultDeny = 0;
|
||||
+ term_printf("acl: policy set to 'allow'\n");
|
||||
+ } else if (strcmp(match, "deny") == 0) {
|
||||
+ acl->defaultDeny = 1;
|
||||
+ term_printf("acl: policy set to 'deny'\n");
|
||||
+ } else {
|
||||
+ term_printf("acl: unknown policy '%s', expected 'deny' or 'allow'\n", match);
|
||||
+ }
|
||||
+ } else if ((strcmp(command, "allow") == 0) ||
|
||||
+ (strcmp(command, "deny") == 0)) {
|
||||
+ int deny = strcmp(command, "deny") == 0 ? 1 : 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!match) {
|
||||
+ term_printf("acl: missing match parameter\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (has_index)
|
||||
+ ret = qemu_acl_insert(acl, deny, match, index);
|
||||
+ else
|
||||
+ ret = qemu_acl_append(acl, deny, match);
|
||||
+ if (ret < 0)
|
||||
+ term_printf("acl: unable to add acl entry\n");
|
||||
+ else
|
||||
+ term_printf("acl: added rule at position %d\n", ret);
|
||||
+ } else if (strcmp(command, "remove") == 0) {
|
||||
+ int ret;
|
||||
+
|
||||
+ if (!match) {
|
||||
+ term_printf("acl: missing match parameter\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = qemu_acl_remove(acl, match);
|
||||
+ if (ret < 0)
|
||||
+ term_printf("acl: no matching acl entry\n");
|
||||
+ else
|
||||
+ term_printf("acl: removed rule at position %d\n", ret);
|
||||
+ } else {
|
||||
+ term_printf("acl: unknown command '%s'\n", command);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* Please update qemu-doc.texi when adding or changing commands */
|
||||
static const term_cmd_t term_cmds[] = {
|
||||
{ "help|?", "s?", do_help,
|
||||
@@ -1557,6 +1637,12 @@ static const term_cmd_t term_cmds[] = {
|
||||
{ "set_link", "ss", do_set_link,
|
||||
"name [up|down]", "change the link status of a network adapter" },
|
||||
{ "set_link", "ss", do_set_link, "name [up|down]" },
|
||||
+ { "acl", "sss?i?", do_acl, "<command> <aclname> [<match>] [<index>]\n",
|
||||
+ "acl show vnc.username\n"
|
||||
+ "acl policy vnc.username deny\n"
|
||||
+ "acl allow vnc.username fred\n"
|
||||
+ "acl deny vnc.username bob\n"
|
||||
+ "acl reset vnc.username\n" },
|
||||
{ "cpu_set", "is", do_cpu_set_nr, "cpu [online|offline]", "change cpu state" },
|
||||
#if defined(TARGET_I386) || defined(TARGET_X86_64)
|
||||
{ "drive_add", "iss", drive_hot_add, "pcibus pcidevfn [file=file][,if=type][,bus=n]\n"
|
||||
@@ -2927,3 +3013,12 @@ void monitor_readline(const char *prompt
|
||||
monitor_hd[i]->focus = old_focus[i];
|
||||
}
|
||||
}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * c-indent-level: 4
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 8
|
||||
+ * End:
|
||||
+ */
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/qemu-doc.texi
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/qemu-doc.texi
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/qemu-doc.texi
|
||||
@@ -639,6 +639,19 @@ ensures a data encryption preventing com
|
||||
credentials. See the @ref{vnc_security} section for details on using
|
||||
SASL authentication.
|
||||
|
||||
+@item acl
|
||||
+
|
||||
+Turn on access control lists for checking of the x509 client certificate
|
||||
+and SASL party. For x509 certs, the ACL check is made against the
|
||||
+certificate's distinguished name. This is something that looks like
|
||||
+@code{C=GB,O=ACME,L=Boston,CN=bob}. For SASL party, the ACL check is
|
||||
+made against the username, which depending on the SASL plugin, may
|
||||
+include a realm component, eg @code{bob} or @code{bob\@EXAMPLE.COM}.
|
||||
+When the @option{acl} flag is set, the initial access list will be
|
||||
+empty, with a @code{deny} policy. Thus no one will be allowed to
|
||||
+use the VNC server until the ACLs have been loaded. This can be
|
||||
+achieved using the @code{acl} monitor command.
|
||||
+
|
||||
@end table
|
||||
|
||||
@end table
|
||||
@@ -1389,6 +1402,42 @@ Password: ********
|
||||
|
||||
@end table
|
||||
|
||||
+@item acl @var{subcommand} @var{aclname} @var{match} @var{index}
|
||||
+
|
||||
+Manage access control lists for network services. There are currently
|
||||
+two named access control lists, @var{vnc.x509dname} and @var{vnc.username}
|
||||
+matching on the x509 client certificate distinguished name, and SASL
|
||||
+username respectively.
|
||||
+
|
||||
+@table @option
|
||||
+@item acl show <aclname>
|
||||
+list all the match rules in the access control list, and the default
|
||||
+policy
|
||||
+@item acl policy <aclname> @code{allow|deny}
|
||||
+set the default access control list policy, used in the event that
|
||||
+none of the explicit rules match. The default policy at startup is
|
||||
+always @code{deny}
|
||||
+@item acl allow <aclname> <match> [<index>]
|
||||
+add a match to the access control list, allowing access. The match will
|
||||
+normally be an exact username or x509 distinguished name, but can
|
||||
+optionally include wildcard globs. eg @code{*\@EXAMPLE.COM} to allow
|
||||
+all users in the @code{EXAMPLE.COM} kerberos realm. The match will
|
||||
+normally be appended to the end of the ACL, but can be inserted
|
||||
+earlier in the list if the optional @code{index} parameter is supplied.
|
||||
+@item acl deny <aclname> <match> [<index>]
|
||||
+add a match to the access control list, denying access. The match will
|
||||
+normally be an exact username or x509 distinguished name, but can
|
||||
+optionally include wildcard globs. eg @code{*\@EXAMPLE.COM} to allow
|
||||
+all users in the @code{EXAMPLE.COM} kerberos realm. The match will
|
||||
+normally be appended to the end of the ACL, but can be inserted
|
||||
+earlier in the list if the optional @code{index} parameter is supplied.
|
||||
+@item acl remove <aclname> <match>
|
||||
+remove the specified match rule from the access control list.
|
||||
+@item acl reset <aclname>
|
||||
+remove all matches from the access control list, and set the default
|
||||
+policy back to @code{deny}.
|
||||
+@end table
|
||||
+
|
||||
@item screendump @var{filename}
|
||||
Save screen into PPM image @var{filename}.
|
||||
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc-auth-sasl.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.c
|
||||
@@ -120,22 +120,32 @@ static int vnc_auth_sasl_check_access(Vn
|
||||
{
|
||||
const void *val;
|
||||
int err;
|
||||
+ int allow;
|
||||
|
||||
err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val);
|
||||
if (err != SASL_OK) {
|
||||
- VNC_DEBUG("cannot query SASL username on connection %d (%s)\n",
|
||||
+ VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n",
|
||||
err, sasl_errstring(err, NULL, NULL));
|
||||
return -1;
|
||||
}
|
||||
if (val == NULL) {
|
||||
- VNC_DEBUG("no client username was found\n");
|
||||
+ VNC_DEBUG("no client username was found, denying access\n");
|
||||
return -1;
|
||||
}
|
||||
VNC_DEBUG("SASL client username %s\n", (const char *)val);
|
||||
|
||||
vs->sasl.username = qemu_strdup((const char*)val);
|
||||
|
||||
- return 0;
|
||||
+ if (vs->vd->sasl.acl == NULL) {
|
||||
+ VNC_DEBUG("no ACL activated, allowing access\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username);
|
||||
+
|
||||
+ VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username,
|
||||
+ allow ? "allowed" : "denied");
|
||||
+ return allow ? 0 : -1;
|
||||
}
|
||||
|
||||
static int vnc_auth_sasl_check_ssf(VncState *vs)
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc-auth-sasl.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc-auth-sasl.h
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <sasl/sasl.h>
|
||||
|
||||
typedef struct VncStateSASL VncStateSASL;
|
||||
+typedef struct VncDisplaySASL VncDisplaySASL;
|
||||
+
|
||||
+#include "acl.h"
|
||||
|
||||
struct VncStateSASL {
|
||||
sasl_conn_t *conn;
|
||||
@@ -56,6 +59,10 @@ struct VncStateSASL {
|
||||
char *mechlist;
|
||||
};
|
||||
|
||||
+struct VncDisplaySASL {
|
||||
+ qemu_acl *acl;
|
||||
+};
|
||||
+
|
||||
void vnc_sasl_client_cleanup(VncState *vs);
|
||||
|
||||
long vnc_client_read_sasl(VncState *vs);
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.c
|
||||
@@ -255,6 +255,25 @@ int vnc_tls_validate_certificate(struct
|
||||
gnutls_strerror (ret));
|
||||
return -1;
|
||||
}
|
||||
+
|
||||
+ if (vs->vd->tls.x509verify) {
|
||||
+ int allow;
|
||||
+ if (!vs->vd->tls.acl) {
|
||||
+ VNC_DEBUG("no ACL activated, allowing access");
|
||||
+ gnutls_x509_crt_deinit (cert);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ allow = qemu_acl_party_is_allowed(vs->vd->tls.acl,
|
||||
+ vs->tls.dname);
|
||||
+
|
||||
+ VNC_DEBUG("TLS x509 ACL check for %s is %s\n",
|
||||
+ vs->tls.dname, allow ? "allowed" : "denied");
|
||||
+ if (!allow) {
|
||||
+ gnutls_x509_crt_deinit (cert);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
gnutls_x509_crt_deinit (cert);
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc-tls.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc-tls.h
|
||||
@@ -31,6 +31,8 @@
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
+#include "acl.h"
|
||||
+
|
||||
enum {
|
||||
VNC_WIREMODE_CLEAR,
|
||||
VNC_WIREMODE_TLS,
|
||||
@@ -42,6 +44,7 @@ typedef struct VncStateTLS VncStateTLS;
|
||||
/* Server state */
|
||||
struct VncDisplayTLS {
|
||||
int x509verify; /* Non-zero if server requests & validates client cert */
|
||||
+ qemu_acl *acl;
|
||||
|
||||
/* Paths to x509 certs/keys */
|
||||
char *x509cacert;
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.c
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "sysemu.h"
|
||||
#include "qemu_socket.h"
|
||||
#include "qemu-timer.h"
|
||||
+#include "acl.h"
|
||||
|
||||
#define VNC_REFRESH_INTERVAL (1000 / 30)
|
||||
|
||||
@@ -2082,6 +2083,7 @@ int vnc_display_open(DisplayState *ds, c
|
||||
int sasl = 0;
|
||||
int saslErr;
|
||||
#endif
|
||||
+ int acl = 0;
|
||||
|
||||
if (!vnc_display)
|
||||
return -1;
|
||||
@@ -2138,9 +2140,28 @@ int vnc_display_open(DisplayState *ds, c
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
+ } else if (strncmp(options, "acl", 3) == 0) {
|
||||
+ acl = 1;
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_VNC_TLS
|
||||
+ if (acl && x509 && vs->tls.x509verify) {
|
||||
+ if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
|
||||
+ fprintf(stderr, "Failed to create x509 dname ACL\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+#ifdef CONFIG_VNC_SASL
|
||||
+ if (acl && sasl) {
|
||||
+ if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
|
||||
+ fprintf(stderr, "Failed to create username ACL\n");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Combinations we support here:
|
||||
*
|
||||
Index: kvm-84.git-snapshot-20090303/qemu/vnc.h
|
||||
===================================================================
|
||||
--- kvm-84.git-snapshot-20090303.orig/qemu/vnc.h
|
||||
+++ kvm-84.git-snapshot-20090303/qemu/vnc.h
|
||||
@@ -98,6 +98,9 @@ struct VncDisplay
|
||||
int subauth; /* Used by VeNCrypt */
|
||||
VncDisplayTLS tls;
|
||||
#endif
|
||||
+#ifdef CONFIG_VNC_SASL
|
||||
+ VncDisplaySASL sasl;
|
||||
+#endif
|
||||
};
|
||||
|
||||
struct VncState
|
45
qemu.spec
45
qemu.spec
@ -1,7 +1,7 @@
|
||||
Summary: QEMU is a FAST! processor emulator
|
||||
Name: qemu
|
||||
Version: 0.10
|
||||
Release: 0.5.kvm20090303git%{?dist}
|
||||
Release: 0.6.kvm20090310git%{?dist}
|
||||
# I have mistakenly thought the revision name would be 1.0.
|
||||
# So 0.10 series get Epoch = 1
|
||||
Epoch: 2
|
||||
@ -10,25 +10,12 @@ Group: Development/Tools
|
||||
URL: http://www.qemu.org/
|
||||
#Source0: http://www.qemu.org/%{name}-%{version}.tar.gz
|
||||
# FIXME: Say how to get the sources
|
||||
Source0: kvm-84.git-snapshot-20090303.tar.gz
|
||||
Source0: kvm-84.git-snapshot-20090310.tar.gz
|
||||
Source1: qemu.init
|
||||
Source2: kvm.modules
|
||||
|
||||
# VNC SASL authentication support
|
||||
# Not upstream yet, but approved for commit immediately
|
||||
# after this release
|
||||
Patch1: qemu-sasl-01-tls-handshake-fix.patch
|
||||
Patch2: qemu-sasl-02-vnc-monitor-info.patch
|
||||
Patch3: qemu-sasl-03-display-keymaps.patch
|
||||
Patch4: qemu-sasl-04-vnc-struct.patch
|
||||
Patch5: qemu-sasl-05-vnc-tls-vencrypt.patch
|
||||
Patch6: qemu-sasl-06-vnc-sasl.patch
|
||||
Patch7: qemu-sasl-07-vnc-monitor-authinfo.patch
|
||||
Patch8: qemu-sasl-08-vnc-acl-mgmt.patch
|
||||
Patch9: kvm-upstream-ppc.patch
|
||||
Patch10: kvm-fix-strayR.patch
|
||||
# NB, delibrately not including patch 09 which is not
|
||||
# intended for commit
|
||||
Patch1: kvm-upstream-ppc.patch
|
||||
Patch2: kvm-fix-strayR.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: SDL-devel zlib-devel which texi2html gnutls-devel cyrus-sasl-devel
|
||||
@ -190,25 +177,9 @@ such as kvmtrace and kvm_stat.
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%setup -q -n kvm-84.git-snapshot-20090303
|
||||
# 01-tls-handshake-fix
|
||||
%setup -q -n kvm-84.git-snapshot-20090310
|
||||
%patch1 -p1
|
||||
# 02-vnc-monitor-info
|
||||
%patch2 -p1
|
||||
# 03-display-keymaps
|
||||
%patch3 -p1
|
||||
# 04-vnc-struct
|
||||
%patch4 -p1
|
||||
# 05-vnc-tls-vencrypt
|
||||
%patch5 -p1
|
||||
# 06-vnc-sasl
|
||||
%patch6 -p1
|
||||
# 07-vnc-monitor-authinfo
|
||||
%patch7 -p1
|
||||
# 08-vnc-acl-mgmt
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
|
||||
%build
|
||||
# systems like rhel build system does not have a recent enough linker so
|
||||
@ -258,7 +229,7 @@ cd qemu
|
||||
sparc32plus-linux-user" \
|
||||
--prefix=%{_prefix} \
|
||||
--interp-prefix=%{_prefix}/qemu-%%M \
|
||||
--kerneldir=$(pwd)/../kernel --prefix=%{_prefix} \
|
||||
--kerneldir=$(pwd)/../kernel --prefix=%{_prefix} \
|
||||
--disable-kvm \
|
||||
--extra-ldflags=$extraldflags
|
||||
|
||||
@ -438,6 +409,10 @@ fi
|
||||
%{_mandir}/man1/qemu-img.1*
|
||||
|
||||
%changelog
|
||||
* Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.6.kvm20090310git
|
||||
- updated to kvm20090310git
|
||||
- removed sasl patches (already in this release)
|
||||
|
||||
* Tue Mar 10 2009 Glauber Costa <glommer@redhat.com> - 2:0.10-0.5.kvm20090303git
|
||||
- kvm.modules were being wrongly mentioned at %%install.
|
||||
- update description for the x86 system package to include kvm support
|
||||
|
Loading…
Reference in New Issue
Block a user