|
Daniel P. Berrange |
42af21 |
This patch introduces a generic internal API for access control lists
|
|
Daniel P. Berrange |
42af21 |
to be used by network servers in QEMU. It adds support for checking
|
|
Daniel P. Berrange |
42af21 |
these ACL in the VNC server, in two places. The first ACL is for the
|
|
Daniel P. Berrange |
42af21 |
SASL authentication mechanism, checking the SASL username. This ACL
|
|
Daniel P. Berrange |
42af21 |
is called 'vnc.username'. The second is for the TLS authentication
|
|
Daniel P. Berrange |
42af21 |
mechanism, when x509 client certificates are turned on, checking against
|
|
Daniel P. Berrange |
42af21 |
the Distinguished Name of the client. This ACL is called 'vnc.x509dname'
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
The internal API provides for an ACL with the following characteristics
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
- A unique name, eg vnc.username, and vnc.x509dname.
|
|
Daniel P. Berrange |
42af21 |
- A default policy, allow or deny
|
|
Daniel P. Berrange |
42af21 |
- An ordered series of match rules, with allow or deny policy
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
If none of the match rules apply, then the default policy is
|
|
Daniel P. Berrange |
42af21 |
used.
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
There is a monitor API to manipulate the ACLs, which I'll describe via
|
|
Daniel P. Berrange |
42af21 |
examples
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl show vnc.username
|
|
Daniel P. Berrange |
42af21 |
policy: allow
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl policy vnc.username denya
|
|
Daniel P. Berrange |
42af21 |
acl: policy set to 'deny'
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl allow vnc.username fred
|
|
Daniel P. Berrange |
42af21 |
acl: added rule at position 1
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl allow vnc.username bob
|
|
Daniel P. Berrange |
42af21 |
acl: added rule at position 2
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl allow vnc.username joe 1
|
|
Daniel P. Berrange |
42af21 |
acl: added rule at position 1
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl show vnc.username
|
|
Daniel P. Berrange |
42af21 |
policy: deny
|
|
Daniel P. Berrange |
42af21 |
0: allow fred
|
|
Daniel P. Berrange |
42af21 |
1: allow joe
|
|
Daniel P. Berrange |
42af21 |
2: allow bob
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl show vnc.x509dname
|
|
Daniel P. Berrange |
42af21 |
policy: allow
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl policy vnc.x509dname deny
|
|
Daniel P. Berrange |
42af21 |
acl: policy set to 'deny'
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl allow vnc.x509dname C=GB,O=ACME,L=London,CN=*
|
|
Daniel P. Berrange |
42af21 |
acl: added rule at position 1
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl allow vnc.x509dname C=GB,O=ACME,L=Boston,CN=bob
|
|
Daniel P. Berrange |
42af21 |
acl: added rule at position 2
|
|
Daniel P. Berrange |
42af21 |
(qemu) acl show vnc.x509dname
|
|
Daniel P. Berrange |
42af21 |
policy: deny
|
|
Daniel P. Berrange |
42af21 |
0: allow C=GB,O=ACME,L=London,CN=*
|
|
Daniel P. Berrange |
42af21 |
1: allow C=GB,O=ACME,L=Boston,CN=bob
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
By default the VNC server will not use any ACLs, allowing access to
|
|
Daniel P. Berrange |
42af21 |
the server if the user successfully authenticates. To enable use of
|
|
Daniel P. Berrange |
42af21 |
ACLs to restrict user access, the ',acl' flag should be given when
|
|
Daniel P. Berrange |
42af21 |
starting QEMU. The initial ACL activated will be a 'deny all' policy
|
|
Daniel P. Berrange |
42af21 |
and should be customized using monitor commands.
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
eg enable SASL auth and ACLs
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
qemu .... -vnc localhost:1,sasl,acl
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
The next patch will provide a way to load a pre-defined ACL when
|
|
Daniel P. Berrange |
42af21 |
starting up
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
Makefile | 6 +
|
|
Daniel P. Berrange |
42af21 |
b/acl.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Daniel P. Berrange |
42af21 |
b/acl.h | 74 ++++++++++++++++++++++
|
|
Daniel P. Berrange |
42af21 |
configure | 18 +++++
|
|
Daniel P. Berrange |
42af21 |
monitor.c | 95 ++++++++++++++++++++++++++++
|
|
Daniel P. Berrange |
42af21 |
qemu-doc.texi | 49 ++++++++++++++
|
|
Daniel P. Berrange |
42af21 |
vnc-auth-sasl.c | 16 +++-
|
|
Daniel P. Berrange |
42af21 |
vnc-auth-sasl.h | 7 ++
|
|
Daniel P. Berrange |
42af21 |
vnc-tls.c | 19 +++++
|
|
Daniel P. Berrange |
42af21 |
vnc-tls.h | 3
|
|
Daniel P. Berrange |
42af21 |
vnc.c | 21 ++++++
|
|
Daniel P. Berrange |
42af21 |
vnc.h | 3
|
|
Daniel P. Berrange |
42af21 |
12 files changed, 491 insertions(+), 5 deletions(-)
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 Makefile
|
|
Daniel P. Berrange |
42af21 |
--- a/Makefile Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/Makefile Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -144,7 +144,7 @@ endif
|
|
Daniel P. Berrange |
42af21 |
ifdef CONFIG_CURSES
|
|
Daniel P. Berrange |
42af21 |
OBJS+=curses.o
|
|
Daniel P. Berrange |
42af21 |
endif
|
|
Daniel P. Berrange |
42af21 |
-OBJS+=vnc.o d3des.o
|
|
Daniel P. Berrange |
42af21 |
+OBJS+=vnc.o acl.o d3des.o
|
|
Daniel P. Berrange |
42af21 |
ifdef CONFIG_VNC_TLS
|
|
Daniel P. Berrange |
42af21 |
OBJS+=vnc-tls.o vnc-auth-vencrypt.o
|
|
Daniel P. Berrange |
42af21 |
endif
|
|
Daniel P. Berrange |
42af21 |
@@ -174,9 +174,11 @@ sdl.o: sdl.c keymaps.h sdl_keysym.h
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
sdl.o audio/sdlaudio.o: CFLAGS += $(SDL_CFLAGS)
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+acl.o: acl.h acl.c
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
vnc.h: vnc-tls.h vnc-auth-vencrypt.h vnc-auth-sasl.h keymaps.h
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
-vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h
|
|
Daniel P. Berrange |
42af21 |
+vnc.o: vnc.c vnc.h vnc_keysym.h vnchextile.h d3des.c d3des.h acl.h
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
vnc.o: CFLAGS += $(CONFIG_VNC_TLS_CFLAGS)
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 acl.c
|
|
Daniel P. Berrange |
42af21 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/acl.c Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -0,0 +1,185 @@
|
|
Daniel P. Berrange |
42af21 |
+/*
|
|
Daniel P. Berrange |
42af21 |
+ * QEMU access control list management
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * Copyright (C) 2009 Red Hat, Inc
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Daniel P. Berrange |
42af21 |
+ * of this software and associated documentation files (the "Software"), to deal
|
|
Daniel P. Berrange |
42af21 |
+ * in the Software without restriction, including without limitation the rights
|
|
Daniel P. Berrange |
42af21 |
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
Daniel P. Berrange |
42af21 |
+ * copies of the Software, and to permit persons to whom the Software is
|
|
Daniel P. Berrange |
42af21 |
+ * furnished to do so, subject to the following conditions:
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * The above copyright notice and this permission notice shall be included in
|
|
Daniel P. Berrange |
42af21 |
+ * all copies or substantial portions of the Software.
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Daniel P. Berrange |
42af21 |
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Daniel P. Berrange |
42af21 |
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
Daniel P. Berrange |
42af21 |
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
Daniel P. Berrange |
42af21 |
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Daniel P. Berrange |
42af21 |
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
Daniel P. Berrange |
42af21 |
+ * THE SOFTWARE.
|
|
Daniel P. Berrange |
42af21 |
+ */
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+#include "qemu-common.h"
|
|
Daniel P. Berrange |
42af21 |
+#include "sysemu.h"
|
|
Daniel P. Berrange |
42af21 |
+#include "acl.h"
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+#ifdef HAVE_FNMATCH_H
|
|
Daniel P. Berrange |
42af21 |
+#include <fnmatch.h>
|
|
Daniel P. Berrange |
42af21 |
+#endif
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+static unsigned int nacls = 0;
|
|
Daniel P. Berrange |
42af21 |
+static qemu_acl **acls = NULL;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+qemu_acl *qemu_acl_find(const char *aclname)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ int i;
|
|
Daniel P. Berrange |
42af21 |
+ for (i = 0 ; i < nacls ; i++) {
|
|
Daniel P. Berrange |
42af21 |
+ if (strcmp(acls[i]->aclname, aclname) == 0)
|
|
Daniel P. Berrange |
42af21 |
+ return acls[i];
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ return NULL;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+qemu_acl *qemu_acl_init(const char *aclname)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl *acl;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ acl = qemu_acl_find(aclname);
|
|
Daniel P. Berrange |
42af21 |
+ if (acl)
|
|
Daniel P. Berrange |
42af21 |
+ return acl;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ acl = qemu_malloc(sizeof(*acl));
|
|
Daniel P. Berrange |
42af21 |
+ acl->aclname = qemu_strdup(aclname);
|
|
Daniel P. Berrange |
42af21 |
+ /* Deny by default, so there is no window of "open
|
|
Daniel P. Berrange |
42af21 |
+ * access" between QEMU starting, and the user setting
|
|
Daniel P. Berrange |
42af21 |
+ * up ACLs in the monitor */
|
|
Daniel P. Berrange |
42af21 |
+ acl->defaultDeny = 1;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ acl->nentries = 0;
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_INIT(&acl->entries);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1));
|
|
Daniel P. Berrange |
42af21 |
+ acls[nacls] = acl;
|
|
Daniel P. Berrange |
42af21 |
+ nacls++;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ return acl;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_party_is_allowed(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ const char *party)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *entry;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
|
Daniel P. Berrange |
42af21 |
+#ifdef HAVE_FNMATCH_H
|
|
Daniel P. Berrange |
42af21 |
+ if (fnmatch(entry->match, party, 0) == 0)
|
|
Daniel P. Berrange |
42af21 |
+ return entry->deny ? 0 : 1;
|
|
Daniel P. Berrange |
42af21 |
+#else
|
|
Daniel P. Berrange |
42af21 |
+ /* No fnmatch, so fallback to exact string matching
|
|
Daniel P. Berrange |
42af21 |
+ * instead of allowing wildcards */
|
|
Daniel P. Berrange |
42af21 |
+ if (strcmp(entry->match, party) == 0)
|
|
Daniel P. Berrange |
42af21 |
+ return entry->deny ? 0 : 1;
|
|
Daniel P. Berrange |
42af21 |
+#endif
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ return acl->defaultDeny ? 0 : 1;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+void qemu_acl_reset(qemu_acl *acl)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *entry;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ /* Put back to deny by default, so there is no window
|
|
Daniel P. Berrange |
42af21 |
+ * of "open access" while the user re-initializes the
|
|
Daniel P. Berrange |
42af21 |
+ * access control list */
|
|
Daniel P. Berrange |
42af21 |
+ acl->defaultDeny = 1;
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_REMOVE(&acl->entries, entry, next);
|
|
Daniel P. Berrange |
42af21 |
+ free(entry->match);
|
|
Daniel P. Berrange |
42af21 |
+ free(entry);
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ acl->nentries = 0;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_append(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ int deny,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *entry;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ entry = qemu_malloc(sizeof(*entry));
|
|
Daniel P. Berrange |
42af21 |
+ entry->match = qemu_strdup(match);
|
|
Daniel P. Berrange |
42af21 |
+ entry->deny = deny;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_INSERT_TAIL(&acl->entries, entry, next);
|
|
Daniel P. Berrange |
42af21 |
+ acl->nentries++;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ return acl->nentries;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_insert(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ int deny,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match,
|
|
Daniel P. Berrange |
42af21 |
+ int index)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *entry;
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *tmp;
|
|
Daniel P. Berrange |
42af21 |
+ int i = 0;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (index <= 0)
|
|
Daniel P. Berrange |
42af21 |
+ return -1;
|
|
Daniel P. Berrange |
42af21 |
+ if (index >= acl->nentries)
|
|
Daniel P. Berrange |
42af21 |
+ return qemu_acl_append(acl, deny, match);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ entry = qemu_malloc(sizeof(*entry));
|
|
Daniel P. Berrange |
42af21 |
+ entry->match = qemu_strdup(match);
|
|
Daniel P. Berrange |
42af21 |
+ entry->deny = deny;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_FOREACH(tmp, &acl->entries, next) {
|
|
Daniel P. Berrange |
42af21 |
+ i++;
|
|
Daniel P. Berrange |
42af21 |
+ if (i == index) {
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_INSERT_BEFORE(tmp, entry, next);
|
|
Daniel P. Berrange |
42af21 |
+ acl->nentries++;
|
|
Daniel P. Berrange |
42af21 |
+ break;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ return i;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_remove(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *entry;
|
|
Daniel P. Berrange |
42af21 |
+ int i = 0;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
|
Daniel P. Berrange |
42af21 |
+ i++;
|
|
Daniel P. Berrange |
42af21 |
+ if (strcmp(entry->match, match) == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_REMOVE(&acl->entries, entry, next);
|
|
Daniel P. Berrange |
42af21 |
+ return i;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ return -1;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+/*
|
|
Daniel P. Berrange |
42af21 |
+ * Local variables:
|
|
Daniel P. Berrange |
42af21 |
+ * c-indent-level: 4
|
|
Daniel P. Berrange |
42af21 |
+ * c-basic-offset: 4
|
|
Daniel P. Berrange |
42af21 |
+ * tab-width: 8
|
|
Daniel P. Berrange |
42af21 |
+ * End:
|
|
Daniel P. Berrange |
42af21 |
+ */
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 acl.h
|
|
Daniel P. Berrange |
42af21 |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/acl.h Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -0,0 +1,74 @@
|
|
Daniel P. Berrange |
42af21 |
+/*
|
|
Daniel P. Berrange |
42af21 |
+ * QEMU access control list management
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * Copyright (C) 2009 Red Hat, Inc
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
Daniel P. Berrange |
42af21 |
+ * of this software and associated documentation files (the "Software"), to deal
|
|
Daniel P. Berrange |
42af21 |
+ * in the Software without restriction, including without limitation the rights
|
|
Daniel P. Berrange |
42af21 |
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
Daniel P. Berrange |
42af21 |
+ * copies of the Software, and to permit persons to whom the Software is
|
|
Daniel P. Berrange |
42af21 |
+ * furnished to do so, subject to the following conditions:
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * The above copyright notice and this permission notice shall be included in
|
|
Daniel P. Berrange |
42af21 |
+ * all copies or substantial portions of the Software.
|
|
Daniel P. Berrange |
42af21 |
+ *
|
|
Daniel P. Berrange |
42af21 |
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
Daniel P. Berrange |
42af21 |
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
Daniel P. Berrange |
42af21 |
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
Daniel P. Berrange |
42af21 |
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
Daniel P. Berrange |
42af21 |
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Daniel P. Berrange |
42af21 |
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
Daniel P. Berrange |
42af21 |
+ * THE SOFTWARE.
|
|
Daniel P. Berrange |
42af21 |
+ */
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+#ifndef __QEMU_ACL_H__
|
|
Daniel P. Berrange |
42af21 |
+#define __QEMU_ACL_H__
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+#include "sys-queue.h"
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+typedef struct qemu_acl_entry qemu_acl_entry;
|
|
Daniel P. Berrange |
42af21 |
+typedef struct qemu_acl qemu_acl;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+struct qemu_acl_entry {
|
|
Daniel P. Berrange |
42af21 |
+ char *match;
|
|
Daniel P. Berrange |
42af21 |
+ int deny;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_ENTRY(qemu_acl_entry) next;
|
|
Daniel P. Berrange |
42af21 |
+};
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+struct qemu_acl {
|
|
Daniel P. Berrange |
42af21 |
+ char *aclname;
|
|
Daniel P. Berrange |
42af21 |
+ unsigned int nentries;
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_HEAD(,qemu_acl_entry) entries;
|
|
Daniel P. Berrange |
42af21 |
+ int defaultDeny;
|
|
Daniel P. Berrange |
42af21 |
+};
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+qemu_acl *qemu_acl_init(const char *aclname);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+qemu_acl *qemu_acl_find(const char *aclname);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_party_is_allowed(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ const char *party);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+void qemu_acl_reset(qemu_acl *acl);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_append(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ int deny,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match);
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_insert(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ int deny,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match,
|
|
Daniel P. Berrange |
42af21 |
+ int index);
|
|
Daniel P. Berrange |
42af21 |
+int qemu_acl_remove(qemu_acl *acl,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+#endif /* __QEMU_ACL_H__ */
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+/*
|
|
Daniel P. Berrange |
42af21 |
+ * Local variables:
|
|
Daniel P. Berrange |
42af21 |
+ * c-indent-level: 4
|
|
Daniel P. Berrange |
42af21 |
+ * c-basic-offset: 4
|
|
Daniel P. Berrange |
42af21 |
+ * tab-width: 8
|
|
Daniel P. Berrange |
42af21 |
+ * End:
|
|
Daniel P. Berrange |
42af21 |
+ */
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 configure
|
|
Daniel P. Berrange |
42af21 |
--- a/configure Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/configure Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -846,6 +846,21 @@ EOF
|
|
Daniel P. Berrange |
42af21 |
fi
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
##########################################
|
|
Daniel P. Berrange |
42af21 |
+# fnmatch() probe, used for ACL routines
|
|
Daniel P. Berrange |
42af21 |
+fnmatch="no"
|
|
Daniel P. Berrange |
42af21 |
+cat > $TMPC << EOF
|
|
Daniel P. Berrange |
42af21 |
+#include <fnmatch.h>
|
|
Daniel P. Berrange |
42af21 |
+int main(void)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ fnmatch("foo", "foo", 0);
|
|
Daniel P. Berrange |
42af21 |
+ return 0;
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+EOF
|
|
Daniel P. Berrange |
42af21 |
+if $cc $ARCH_CFLAGS -o $TMPE $TMPC > /dev/null 2> /dev/null ; then
|
|
Daniel P. Berrange |
42af21 |
+ fnmatch="yes"
|
|
Daniel P. Berrange |
42af21 |
+fi
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+##########################################
|
|
Daniel P. Berrange |
42af21 |
# vde libraries probe
|
|
Daniel P. Berrange |
42af21 |
if test "$vde" = "yes" ; then
|
|
Daniel P. Berrange |
42af21 |
cat > $TMPC << EOF
|
|
Daniel P. Berrange |
42af21 |
@@ -1405,6 +1420,9 @@ if test "$vnc_sasl" = "yes" ; then
|
|
Daniel P. Berrange |
42af21 |
echo "CONFIG_VNC_SASL_LIBS=$vnc_sasl_libs" >> $config_mak
|
|
Daniel P. Berrange |
42af21 |
echo "#define CONFIG_VNC_SASL 1" >> $config_h
|
|
Daniel P. Berrange |
42af21 |
fi
|
|
Daniel P. Berrange |
42af21 |
+if test "$fnmatch" = "yes" ; then
|
|
Daniel P. Berrange |
42af21 |
+ echo "#define HAVE_FNMATCH_H 1" >> $config_h
|
|
Daniel P. Berrange |
42af21 |
+fi
|
|
Daniel P. Berrange |
42af21 |
qemu_version=`head $source_path/VERSION`
|
|
Daniel P. Berrange |
42af21 |
echo "VERSION=$qemu_version" >>$config_mak
|
|
Daniel P. Berrange |
42af21 |
echo "#define QEMU_VERSION \"$qemu_version\"" >> $config_h
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 monitor.c
|
|
Daniel P. Berrange |
42af21 |
--- a/monitor.c Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/monitor.c Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -39,6 +39,7 @@
|
|
Daniel P. Berrange |
42af21 |
#include "qemu-timer.h"
|
|
Daniel P. Berrange |
42af21 |
#include "migration.h"
|
|
Daniel P. Berrange |
42af21 |
#include "kvm.h"
|
|
Daniel P. Berrange |
42af21 |
+#include "acl.h"
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
//#define DEBUG
|
|
Daniel P. Berrange |
42af21 |
//#define DEBUG_COMPLETION
|
|
Daniel P. Berrange |
42af21 |
@@ -1425,6 +1426,85 @@ static void do_info_balloon(void)
|
|
Daniel P. Berrange |
42af21 |
term_printf("balloon: actual=%d\n", (int)(actual >> 20));
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+static void do_acl(const char *command,
|
|
Daniel P. Berrange |
42af21 |
+ const char *aclname,
|
|
Daniel P. Berrange |
42af21 |
+ const char *match,
|
|
Daniel P. Berrange |
42af21 |
+ int has_index,
|
|
Daniel P. Berrange |
42af21 |
+ int index)
|
|
Daniel P. Berrange |
42af21 |
+{
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl *acl;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ acl = qemu_acl_find(aclname);
|
|
Daniel P. Berrange |
42af21 |
+ if (!acl) {
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: unknown list '%s'\n", aclname);
|
|
Daniel P. Berrange |
42af21 |
+ return;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (strcmp(command, "show") == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ int i = 0;
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_entry *entry;
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("policy: %s\n",
|
|
Daniel P. Berrange |
42af21 |
+ acl->defaultDeny ? "deny" : "allow");
|
|
Daniel P. Berrange |
42af21 |
+ TAILQ_FOREACH(entry, &acl->entries, next) {
|
|
Daniel P. Berrange |
42af21 |
+ i++;
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("%d: %s %s\n", i,
|
|
Daniel P. Berrange |
42af21 |
+ entry->deny ? "deny" : "allow",
|
|
Daniel P. Berrange |
42af21 |
+ entry->match);
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ } else if (strcmp(command, "reset") == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl_reset(acl);
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: removed all rules\n");
|
|
Daniel P. Berrange |
42af21 |
+ } else if (strcmp(command, "policy") == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ if (!match) {
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: missing policy parameter\n");
|
|
Daniel P. Berrange |
42af21 |
+ return;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (strcmp(match, "allow") == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ acl->defaultDeny = 0;
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: policy set to 'allow'\n");
|
|
Daniel P. Berrange |
42af21 |
+ } else if (strcmp(match, "deny") == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ acl->defaultDeny = 1;
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: policy set to 'deny'\n");
|
|
Daniel P. Berrange |
42af21 |
+ } else {
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: unknown policy '%s', expected 'deny' or 'allow'\n", match);
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ } else if ((strcmp(command, "allow") == 0) ||
|
|
Daniel P. Berrange |
42af21 |
+ (strcmp(command, "deny") == 0)) {
|
|
Daniel P. Berrange |
42af21 |
+ int deny = strcmp(command, "deny") == 0 ? 1 : 0;
|
|
Daniel P. Berrange |
42af21 |
+ int ret;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (!match) {
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: missing match parameter\n");
|
|
Daniel P. Berrange |
42af21 |
+ return;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (has_index)
|
|
Daniel P. Berrange |
42af21 |
+ ret = qemu_acl_insert(acl, deny, match, index);
|
|
Daniel P. Berrange |
42af21 |
+ else
|
|
Daniel P. Berrange |
42af21 |
+ ret = qemu_acl_append(acl, deny, match);
|
|
Daniel P. Berrange |
42af21 |
+ if (ret < 0)
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: unable to add acl entry\n");
|
|
Daniel P. Berrange |
42af21 |
+ else
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: added rule at position %d\n", ret);
|
|
Daniel P. Berrange |
42af21 |
+ } else if (strcmp(command, "remove") == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ int ret;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (!match) {
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: missing match parameter\n");
|
|
Daniel P. Berrange |
42af21 |
+ return;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ ret = qemu_acl_remove(acl, match);
|
|
Daniel P. Berrange |
42af21 |
+ if (ret < 0)
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: no matching acl entry\n");
|
|
Daniel P. Berrange |
42af21 |
+ else
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: removed rule at position %d\n", ret);
|
|
Daniel P. Berrange |
42af21 |
+ } else {
|
|
Daniel P. Berrange |
42af21 |
+ term_printf("acl: unknown command '%s'\n", command);
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
/* Please update qemu-doc.texi when adding or changing commands */
|
|
Daniel P. Berrange |
42af21 |
static const term_cmd_t term_cmds[] = {
|
|
Daniel P. Berrange |
42af21 |
{ "help|?", "s?", do_help,
|
|
Daniel P. Berrange |
42af21 |
@@ -1529,6 +1609,12 @@ static const term_cmd_t term_cmds[] = {
|
|
Daniel P. Berrange |
42af21 |
"target", "request VM to change it's memory allocation (in MB)" },
|
|
Daniel P. Berrange |
42af21 |
{ "set_link", "ss", do_set_link,
|
|
Daniel P. Berrange |
42af21 |
"name [up|down]", "change the link status of a network adapter" },
|
|
Daniel P. Berrange |
42af21 |
+ { "acl", "sss?i?", do_acl, "<command> <aclname> [<match>] [<index>]\n",
|
|
Daniel P. Berrange |
42af21 |
+ "acl show vnc.username\n"
|
|
Daniel P. Berrange |
42af21 |
+ "acl policy vnc.username deny\n"
|
|
Daniel P. Berrange |
42af21 |
+ "acl allow vnc.username fred\n"
|
|
Daniel P. Berrange |
42af21 |
+ "acl deny vnc.username bob\n"
|
|
Daniel P. Berrange |
42af21 |
+ "acl reset vnc.username\n" },
|
|
Daniel P. Berrange |
42af21 |
{ NULL, NULL, },
|
|
Daniel P. Berrange |
42af21 |
};
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
@@ -2891,3 +2977,12 @@ void monitor_readline(const char *prompt
|
|
Daniel P. Berrange |
42af21 |
monitor_hd[i]->focus = old_focus[i];
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+/*
|
|
Daniel P. Berrange |
42af21 |
+ * Local variables:
|
|
Daniel P. Berrange |
42af21 |
+ * c-indent-level: 4
|
|
Daniel P. Berrange |
42af21 |
+ * c-basic-offset: 4
|
|
Daniel P. Berrange |
42af21 |
+ * tab-width: 8
|
|
Daniel P. Berrange |
42af21 |
+ * End:
|
|
Daniel P. Berrange |
42af21 |
+ */
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 qemu-doc.texi
|
|
Daniel P. Berrange |
42af21 |
--- a/qemu-doc.texi Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/qemu-doc.texi Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -631,6 +631,19 @@ ensures a data encryption preventing com
|
|
Daniel P. Berrange |
42af21 |
credentials. See the @ref{vnc_security} section for details on using
|
|
Daniel P. Berrange |
42af21 |
SASL authentication.
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+@item acl
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+Turn on access control lists for checking of the x509 client certificate
|
|
Daniel P. Berrange |
42af21 |
+and SASL party. For x509 certs, the ACL check is made against the
|
|
Daniel P. Berrange |
42af21 |
+certificate's distinguished name. This is something that looks like
|
|
Daniel P. Berrange |
42af21 |
+@code{C=GB,O=ACME,L=Boston,CN=bob}. For SASL party, the ACL check is
|
|
Daniel P. Berrange |
42af21 |
+made against the username, which depending on the SASL plugin, may
|
|
Daniel P. Berrange |
42af21 |
+include a realm component, eg @code{bob} or @code{bob\@EXAMPLE.COM}.
|
|
Daniel P. Berrange |
42af21 |
+When the @option{acl} flag is set, the initial access list will be
|
|
Daniel P. Berrange |
42af21 |
+empty, with a @code{deny} policy. Thus no one will be allowed to
|
|
Daniel P. Berrange |
42af21 |
+use the VNC server until the ACLs have been loaded. This can be
|
|
Daniel P. Berrange |
42af21 |
+achieved using the @code{acl} monitor command.
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
@end table
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
@end table
|
|
Daniel P. Berrange |
42af21 |
@@ -1392,6 +1405,42 @@ Password: ********
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
@end table
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+@item acl @var{subcommand} @var{aclname} @var{match} @var{index}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+Manage access control lists for network services. There are currently
|
|
Daniel P. Berrange |
42af21 |
+two named access control lists, @var{vnc.x509dname} and @var{vnc.username}
|
|
Daniel P. Berrange |
42af21 |
+matching on the x509 client certificate distinguished name, and SASL
|
|
Daniel P. Berrange |
42af21 |
+username respectively.
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+@table @option
|
|
Daniel P. Berrange |
42af21 |
+@item acl show <aclname>
|
|
Daniel P. Berrange |
42af21 |
+list all the match rules in the access control list, and the default
|
|
Daniel P. Berrange |
42af21 |
+policy
|
|
Daniel P. Berrange |
42af21 |
+@item acl policy <aclname> @code{allow|deny}
|
|
Daniel P. Berrange |
42af21 |
+set the default access control list policy, used in the event that
|
|
Daniel P. Berrange |
42af21 |
+none of the explicit rules match. The default policy at startup is
|
|
Daniel P. Berrange |
42af21 |
+always @code{deny}
|
|
Daniel P. Berrange |
42af21 |
+@item acl allow <aclname> <match> [<index>]
|
|
Daniel P. Berrange |
42af21 |
+add a match to the access control list, allowing access. The match will
|
|
Daniel P. Berrange |
42af21 |
+normally be an exact username or x509 distinguished name, but can
|
|
Daniel P. Berrange |
42af21 |
+optionally include wildcard globs. eg @code{*\@EXAMPLE.COM} to allow
|
|
Daniel P. Berrange |
42af21 |
+all users in the @code{EXAMPLE.COM} kerberos realm. The match will
|
|
Daniel P. Berrange |
42af21 |
+normally be appended to the end of the ACL, but can be inserted
|
|
Daniel P. Berrange |
42af21 |
+earlier in the list if the optional @code{index} parameter is supplied.
|
|
Daniel P. Berrange |
42af21 |
+@item acl deny <aclname> <match> [<index>]
|
|
Daniel P. Berrange |
42af21 |
+add a match to the access control list, denying access. The match will
|
|
Daniel P. Berrange |
42af21 |
+normally be an exact username or x509 distinguished name, but can
|
|
Daniel P. Berrange |
42af21 |
+optionally include wildcard globs. eg @code{*\@EXAMPLE.COM} to allow
|
|
Daniel P. Berrange |
42af21 |
+all users in the @code{EXAMPLE.COM} kerberos realm. The match will
|
|
Daniel P. Berrange |
42af21 |
+normally be appended to the end of the ACL, but can be inserted
|
|
Daniel P. Berrange |
42af21 |
+earlier in the list if the optional @code{index} parameter is supplied.
|
|
Daniel P. Berrange |
42af21 |
+@item acl remove <aclname> <match>
|
|
Daniel P. Berrange |
42af21 |
+remove the specified match rule from the access control list.
|
|
Daniel P. Berrange |
42af21 |
+@item acl reset <aclname>
|
|
Daniel P. Berrange |
42af21 |
+remove all matches from the access control list, and set the default
|
|
Daniel P. Berrange |
42af21 |
+policy back to @code{deny}.
|
|
Daniel P. Berrange |
42af21 |
+@end table
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
@item screendump @var{filename}
|
|
Daniel P. Berrange |
42af21 |
Save screen into PPM image @var{filename}.
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 vnc-auth-sasl.c
|
|
Daniel P. Berrange |
42af21 |
--- a/vnc-auth-sasl.c Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/vnc-auth-sasl.c Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -120,22 +120,32 @@ static int vnc_auth_sasl_check_access(Vn
|
|
Daniel P. Berrange |
42af21 |
{
|
|
Daniel P. Berrange |
42af21 |
const void *val;
|
|
Daniel P. Berrange |
42af21 |
int err;
|
|
Daniel P. Berrange |
42af21 |
+ int allow;
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
err = sasl_getprop(vs->sasl.conn, SASL_USERNAME, &val;;
|
|
Daniel P. Berrange |
42af21 |
if (err != SASL_OK) {
|
|
Daniel P. Berrange |
42af21 |
- VNC_DEBUG("cannot query SASL username on connection %d (%s)\n",
|
|
Daniel P. Berrange |
42af21 |
+ VNC_DEBUG("cannot query SASL username on connection %d (%s), denying access\n",
|
|
Daniel P. Berrange |
42af21 |
err, sasl_errstring(err, NULL, NULL));
|
|
Daniel P. Berrange |
42af21 |
return -1;
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
if (val == NULL) {
|
|
Daniel P. Berrange |
42af21 |
- VNC_DEBUG("no client username was found\n");
|
|
Daniel P. Berrange |
42af21 |
+ VNC_DEBUG("no client username was found, denying access\n");
|
|
Daniel P. Berrange |
42af21 |
return -1;
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
VNC_DEBUG("SASL client username %s\n", (const char *)val);
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
vs->sasl.username = qemu_strdup((const char*)val);
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
- return 0;
|
|
Daniel P. Berrange |
42af21 |
+ if (vs->vd->sasl.acl == NULL) {
|
|
Daniel P. Berrange |
42af21 |
+ VNC_DEBUG("no ACL activated, allowing access\n");
|
|
Daniel P. Berrange |
42af21 |
+ return 0;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ allow = qemu_acl_party_is_allowed(vs->vd->sasl.acl, vs->sasl.username);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ VNC_DEBUG("SASL client %s %s by ACL\n", vs->sasl.username,
|
|
Daniel P. Berrange |
42af21 |
+ allow ? "allowed" : "denied");
|
|
Daniel P. Berrange |
42af21 |
+ return allow ? 0 : -1;
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
static int vnc_auth_sasl_check_ssf(VncState *vs)
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 vnc-auth-sasl.h
|
|
Daniel P. Berrange |
42af21 |
--- a/vnc-auth-sasl.h Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/vnc-auth-sasl.h Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -30,6 +30,9 @@
|
|
Daniel P. Berrange |
42af21 |
#include <sasl/sasl.h>
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
typedef struct VncStateSASL VncStateSASL;
|
|
Daniel P. Berrange |
42af21 |
+typedef struct VncDisplaySASL VncDisplaySASL;
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+#include "acl.h"
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
struct VncStateSASL {
|
|
Daniel P. Berrange |
42af21 |
sasl_conn_t *conn;
|
|
Daniel P. Berrange |
42af21 |
@@ -56,6 +59,10 @@ struct VncStateSASL {
|
|
Daniel P. Berrange |
42af21 |
char *mechlist;
|
|
Daniel P. Berrange |
42af21 |
};
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+struct VncDisplaySASL {
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl *acl;
|
|
Daniel P. Berrange |
42af21 |
+};
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
void vnc_sasl_client_cleanup(VncState *vs);
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
long vnc_client_read_sasl(VncState *vs);
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 vnc-tls.c
|
|
Daniel P. Berrange |
42af21 |
--- a/vnc-tls.c Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/vnc-tls.c Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -255,6 +255,25 @@ int vnc_tls_validate_certificate(struct
|
|
Daniel P. Berrange |
42af21 |
gnutls_strerror (ret));
|
|
Daniel P. Berrange |
42af21 |
return -1;
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ if (vs->vd->tls.x509verify) {
|
|
Daniel P. Berrange |
42af21 |
+ int allow;
|
|
Daniel P. Berrange |
42af21 |
+ if (!vs->vd->tls.acl) {
|
|
Daniel P. Berrange |
42af21 |
+ VNC_DEBUG("no ACL activated, allowing access");
|
|
Daniel P. Berrange |
42af21 |
+ gnutls_x509_crt_deinit (cert);
|
|
Daniel P. Berrange |
42af21 |
+ continue;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ allow = qemu_acl_party_is_allowed(vs->vd->tls.acl,
|
|
Daniel P. Berrange |
42af21 |
+ vs->tls.dname);
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
+ VNC_DEBUG("TLS x509 ACL check for %s is %s\n",
|
|
Daniel P. Berrange |
42af21 |
+ vs->tls.dname, allow ? "allowed" : "denied");
|
|
Daniel P. Berrange |
42af21 |
+ if (!allow) {
|
|
Daniel P. Berrange |
42af21 |
+ gnutls_x509_crt_deinit (cert);
|
|
Daniel P. Berrange |
42af21 |
+ return -1;
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
gnutls_x509_crt_deinit (cert);
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 vnc-tls.h
|
|
Daniel P. Berrange |
42af21 |
--- a/vnc-tls.h Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/vnc-tls.h Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -31,6 +31,8 @@
|
|
Daniel P. Berrange |
42af21 |
#include <gnutls/gnutls.h>
|
|
Daniel P. Berrange |
42af21 |
#include <gnutls/x509.h>
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+#include "acl.h"
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
enum {
|
|
Daniel P. Berrange |
42af21 |
VNC_WIREMODE_CLEAR,
|
|
Daniel P. Berrange |
42af21 |
VNC_WIREMODE_TLS,
|
|
Daniel P. Berrange |
42af21 |
@@ -42,6 +44,7 @@ typedef struct VncStateTLS VncStateTLS;
|
|
Daniel P. Berrange |
42af21 |
/* Server state */
|
|
Daniel P. Berrange |
42af21 |
struct VncDisplayTLS {
|
|
Daniel P. Berrange |
42af21 |
int x509verify; /* Non-zero if server requests & validates client cert */
|
|
Daniel P. Berrange |
42af21 |
+ qemu_acl *acl;
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
/* Paths to x509 certs/keys */
|
|
Daniel P. Berrange |
42af21 |
char *x509cacert;
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 vnc.c
|
|
Daniel P. Berrange |
42af21 |
--- a/vnc.c Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/vnc.c Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -28,6 +28,7 @@
|
|
Daniel P. Berrange |
42af21 |
#include "sysemu.h"
|
|
Daniel P. Berrange |
42af21 |
#include "qemu_socket.h"
|
|
Daniel P. Berrange |
42af21 |
#include "qemu-timer.h"
|
|
Daniel P. Berrange |
42af21 |
+#include "acl.h"
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
#define VNC_REFRESH_INTERVAL (1000 / 30)
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
@@ -2082,6 +2083,7 @@ int vnc_display_open(DisplayState *ds, c
|
|
Daniel P. Berrange |
42af21 |
int sasl = 0;
|
|
Daniel P. Berrange |
42af21 |
int saslErr;
|
|
Daniel P. Berrange |
42af21 |
#endif
|
|
Daniel P. Berrange |
42af21 |
+ int acl = 0;
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
if (!vnc_display)
|
|
Daniel P. Berrange |
42af21 |
return -1;
|
|
Daniel P. Berrange |
42af21 |
@@ -2138,9 +2140,28 @@ int vnc_display_open(DisplayState *ds, c
|
|
Daniel P. Berrange |
42af21 |
return -1;
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
#endif
|
|
Daniel P. Berrange |
42af21 |
+ } else if (strncmp(options, "acl", 3) == 0) {
|
|
Daniel P. Berrange |
42af21 |
+ acl = 1;
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
}
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
+#ifdef CONFIG_VNC_TLS
|
|
Daniel P. Berrange |
42af21 |
+ if (acl && x509 && vs->tls.x509verify) {
|
|
Daniel P. Berrange |
42af21 |
+ if (!(vs->tls.acl = qemu_acl_init("vnc.x509dname"))) {
|
|
Daniel P. Berrange |
42af21 |
+ fprintf(stderr, "Failed to create x509 dname ACL\n");
|
|
Daniel P. Berrange |
42af21 |
+ exit(1);
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+#endif
|
|
Daniel P. Berrange |
42af21 |
+#ifdef CONFIG_VNC_SASL
|
|
Daniel P. Berrange |
42af21 |
+ if (acl && sasl) {
|
|
Daniel P. Berrange |
42af21 |
+ if (!(vs->sasl.acl = qemu_acl_init("vnc.username"))) {
|
|
Daniel P. Berrange |
42af21 |
+ fprintf(stderr, "Failed to create username ACL\n");
|
|
Daniel P. Berrange |
42af21 |
+ exit(1);
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+ }
|
|
Daniel P. Berrange |
42af21 |
+#endif
|
|
Daniel P. Berrange |
42af21 |
+
|
|
Daniel P. Berrange |
42af21 |
/*
|
|
Daniel P. Berrange |
42af21 |
* Combinations we support here:
|
|
Daniel P. Berrange |
42af21 |
*
|
|
Daniel P. Berrange |
42af21 |
diff -r b1008c5c6c16 vnc.h
|
|
Daniel P. Berrange |
42af21 |
--- a/vnc.h Mon Mar 02 11:13:40 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
+++ b/vnc.h Mon Mar 02 12:11:04 2009 +0000
|
|
Daniel P. Berrange |
42af21 |
@@ -98,6 +98,9 @@ struct VncDisplay
|
|
Daniel P. Berrange |
42af21 |
int subauth; /* Used by VeNCrypt */
|
|
Daniel P. Berrange |
42af21 |
VncDisplayTLS tls;
|
|
Daniel P. Berrange |
42af21 |
#endif
|
|
Daniel P. Berrange |
42af21 |
+#ifdef CONFIG_VNC_SASL
|
|
Daniel P. Berrange |
42af21 |
+ VncDisplaySASL sasl;
|
|
Daniel P. Berrange |
42af21 |
+#endif
|
|
Daniel P. Berrange |
42af21 |
};
|
|
Daniel P. Berrange |
42af21 |
|
|
Daniel P. Berrange |
42af21 |
struct VncState
|