Skip to content

Commit 1ea06ab

Browse files
committed
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/misc-fixes-pull-request' into staging
Merge misc patches # gpg: Signature made Mon 14 Jun 2021 15:14:48 BST # gpg: using RSA key DAF3A6FDB26B62912D0E8E3FBE86EBB415104FDF # gpg: Good signature from "Daniel P. Berrange <[email protected]>" [full] # gpg: aka "Daniel P. Berrange <[email protected]>" [full] # Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF * remotes/berrange-gitlab/tags/misc-fixes-pull-request: usb/dev-mtp: use GDateTime for formatting timestamp for objects block: use GDateTime for formatting timestamp when dumping snapshot info migration: use GDateTime for formatting timestamp in snapshot names block: remove duplicate trace.h include block: add trace point when fdatasync fails block: preserve errno from fdatasync failures softmmu: add trace point when bdrv_flush_all fails migration: add trace point when vm_stop_force_state fails sasl: remove comment about obsolete kerberos versions docs: recommend SCRAM-SHA-256 SASL mech instead of SHA-1 variant docs: document usage of the authorization framework docs: document how to pass secret data to QEMU docs: add table of contents to QAPI references Signed-off-by: Peter Maydell <[email protected]>
2 parents fbe7919 + 970bc16 commit 1ea06ab

17 files changed

+475
-39
lines changed

block/file-posix.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@
106106
#include <xfs/xfs.h>
107107
#endif
108108

109-
#include "trace.h"
110-
111109
/* OS X does not have O_DSYNC */
112110
#ifndef O_DSYNC
113111
#ifdef O_SYNC
@@ -160,7 +158,7 @@ typedef struct BDRVRawState {
160158
bool discard_zeroes:1;
161159
bool use_linux_aio:1;
162160
bool use_linux_io_uring:1;
163-
bool page_cache_inconsistent:1;
161+
int page_cache_inconsistent; /* errno from fdatasync failure */
164162
bool has_fallocate;
165163
bool needs_alignment;
166164
bool drop_cache;
@@ -1333,11 +1331,13 @@ static int handle_aiocb_flush(void *opaque)
13331331
int ret;
13341332

13351333
if (s->page_cache_inconsistent) {
1336-
return -EIO;
1334+
return -s->page_cache_inconsistent;
13371335
}
13381336

13391337
ret = qemu_fdatasync(aiocb->aio_fildes);
13401338
if (ret == -1) {
1339+
trace_file_flush_fdatasync_failed(errno);
1340+
13411341
/* There is no clear definition of the semantics of a failing fsync(),
13421342
* so we may have to assume the worst. The sad truth is that this
13431343
* assumption is correct for Linux. Some pages are now probably marked
@@ -1352,7 +1352,7 @@ static int handle_aiocb_flush(void *opaque)
13521352
* Obviously, this doesn't affect O_DIRECT, which bypasses the page
13531353
* cache. */
13541354
if ((s->open_flags & O_DIRECT) == 0) {
1355-
s->page_cache_inconsistent = true;
1355+
s->page_cache_inconsistent = errno;
13561356
}
13571357
return -errno;
13581358
}

block/qapi.c

+4-7
Original file line numberDiff line numberDiff line change
@@ -663,21 +663,18 @@ BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
663663

664664
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
665665
{
666-
char date_buf[128], clock_buf[128];
666+
char clock_buf[128];
667667
char icount_buf[128] = {0};
668-
struct tm tm;
669-
time_t ti;
670668
int64_t secs;
671669
char *sizing = NULL;
672670

673671
if (!sn) {
674672
qemu_printf("%-10s%-17s%8s%20s%13s%11s",
675673
"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
676674
} else {
677-
ti = sn->date_sec;
678-
localtime_r(&ti, &tm);
679-
strftime(date_buf, sizeof(date_buf),
680-
"%Y-%m-%d %H:%M:%S", &tm);
675+
g_autoptr(GDateTime) date = g_date_time_new_from_unix_local(sn->date_sec);
676+
g_autofree char *date_buf = g_date_time_format(date, "%Y-%m-%d %H:%M:%S");
677+
681678
secs = sn->vm_clock_nsec / 1000000000;
682679
snprintf(clock_buf, sizeof(clock_buf),
683680
"%02d:%02d:%02d.%03d",

block/trace-events

+1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ file_copy_file_range(void *bs, int src, int64_t src_off, int dst, int64_t dst_of
206206
file_FindEjectableOpticalMedia(const char *media) "Matching using %s"
207207
file_setup_cdrom(const char *partition) "Using %s as optical disc"
208208
file_hdev_is_sg(int type, int version) "SG device found: type=%d, version=%d"
209+
file_flush_fdatasync_failed(int err) "errno %d"
209210

210211
# ssh.c
211212
sftp_error(const char *op, const char *ssh_err, int ssh_err_code, int sftp_err_code) "%s failed: %s (libssh error code: %d, sftp error code: %d)"

docs/interop/qemu-ga-ref.rst

+3
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ QEMU Guest Agent Protocol Reference
1010
TODO: display the QEMU version, both here and in our Sphinx manuals
1111
more generally.
1212
13+
.. contents::
14+
:depth: 3
15+
1316
.. qapi-doc:: qga/qapi-schema.json

docs/interop/qemu-qmp-ref.rst

+3
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ QEMU QMP Reference Manual
1010
TODO: display the QEMU version, both here and in our Sphinx manuals
1111
more generally.
1212
13+
.. contents::
14+
:depth: 3
15+
1316
.. qapi-doc:: qapi/qapi-schema.json

docs/interop/qemu-storage-daemon-qmp-ref.rst

+3
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ QEMU Storage Daemon QMP Reference Manual
1010
TODO: display the QEMU version, both here and in our Sphinx manuals
1111
more generally.
1212
13+
.. contents::
14+
:depth: 3
15+
1316
.. qapi-doc:: storage-daemon/qapi/qapi-schema.json

docs/system/authz.rst

+263
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
.. _client authorization:
2+
3+
Client authorization
4+
--------------------
5+
6+
When configuring a QEMU network backend with either TLS certificates or SASL
7+
authentication, access will be granted if the client successfully proves
8+
their identity. If the authorization identity database is scoped to the QEMU
9+
client this may be sufficient. It is common, however, for the identity database
10+
to be much broader and thus authentication alone does not enable sufficient
11+
access control. In this case QEMU provides a flexible system for enforcing
12+
finer grained authorization on clients post-authentication.
13+
14+
Identity providers
15+
~~~~~~~~~~~~~~~~~~
16+
17+
At the time of writing there are two authentication frameworks used by QEMU
18+
that emit an identity upon completion.
19+
20+
* TLS x509 certificate distinguished name.
21+
22+
When configuring the QEMU backend as a network server with TLS, there
23+
are a choice of credentials to use. The most common scenario is to utilize
24+
x509 certificates. The simplest configuration only involves issuing
25+
certificates to the servers, allowing the client to avoid a MITM attack
26+
against their intended server.
27+
28+
It is possible, however, to enable mutual verification by requiring that
29+
the client provide a certificate to the server to prove its own identity.
30+
This is done by setting the property ``verify-peer=yes`` on the
31+
``tls-creds-x509`` object, which is in fact the default.
32+
33+
When peer verification is enabled, client will need to be issued with a
34+
certificate by the same certificate authority as the server. If this is
35+
still not sufficiently strong access control the Distinguished Name of
36+
the certificate can be used as an identity in the QEMU authorization
37+
framework.
38+
39+
* SASL username.
40+
41+
When configuring the QEMU backend as a network server with SASL, upon
42+
completion of the SASL authentication mechanism, a username will be
43+
provided. The format of this username will vary depending on the choice
44+
of mechanism configured for SASL. It might be a simple UNIX style user
45+
``joebloggs``, while if using Kerberos/GSSAPI it can have a realm
46+
attached ``[email protected]``. Whatever format the username is presented
47+
in, it can be used with the QEMU authorization framework.
48+
49+
Authorization drivers
50+
~~~~~~~~~~~~~~~~~~~~~
51+
52+
The QEMU authorization framework is a general purpose design with choice of
53+
user customizable drivers. These are provided as objects that can be
54+
created at startup using the ``-object`` argument, or at runtime using the
55+
``object_add`` monitor command.
56+
57+
Simple
58+
^^^^^^
59+
60+
This authorization driver provides a simple mechanism for granting access
61+
based on an exact match against a single identity. This is useful when it is
62+
known that only a single client is to be allowed access.
63+
64+
A possible use case would be when configuring QEMU for an incoming live
65+
migration. It is known exactly which source QEMU the migration is expected
66+
to arrive from. The x509 certificate associated with this source QEMU would
67+
thus be used as the identity to match against. Alternatively if the virtual
68+
machine is dedicated to a specific tenant, then the VNC server would be
69+
configured with SASL and the username of only that tenant listed.
70+
71+
To create an instance of this driver via QMP:
72+
73+
::
74+
75+
{
76+
"execute": "object-add",
77+
"arguments": {
78+
"qom-type": "authz-simple",
79+
"id": "authz0",
80+
"props": {
81+
"identity": "fred"
82+
}
83+
}
84+
}
85+
86+
87+
Or via the command line
88+
89+
::
90+
91+
-object authz-simple,id=authz0,identity=fred
92+
93+
94+
List
95+
^^^^
96+
97+
In some network backends it will be desirable to grant access to a range of
98+
clients. This authorization driver provides a list mechanism for granting
99+
access by matching identities against a list of permitted one. Each match
100+
rule has an associated policy and a catch all policy applies if no rule
101+
matches. The match can either be done as an exact string comparison, or can
102+
use the shell-like glob syntax, which allows for use of wildcards.
103+
104+
To create an instance of this class via QMP:
105+
106+
::
107+
108+
{
109+
"execute": "object-add",
110+
"arguments": {
111+
"qom-type": "authz-list",
112+
"id": "authz0",
113+
"props": {
114+
"rules": [
115+
{ "match": "fred", "policy": "allow", "format": "exact" },
116+
{ "match": "bob", "policy": "allow", "format": "exact" },
117+
{ "match": "danb", "policy": "deny", "format": "exact" },
118+
{ "match": "dan*", "policy": "allow", "format": "glob" }
119+
],
120+
"policy": "deny"
121+
}
122+
}
123+
}
124+
125+
126+
Due to the way this driver requires setting nested properties, creating
127+
it on the command line will require use of the JSON syntax for ``-object``.
128+
In most cases, however, the next driver will be more suitable.
129+
130+
List file
131+
^^^^^^^^^
132+
133+
This is a variant on the previous driver that allows for a more dynamic
134+
access control policy by storing the match rules in a standalone file
135+
that can be reloaded automatically upon change.
136+
137+
To create an instance of this class via QMP:
138+
139+
::
140+
141+
{
142+
"execute": "object-add",
143+
"arguments": {
144+
"qom-type": "authz-list-file",
145+
"id": "authz0",
146+
"props": {
147+
"filename": "/etc/qemu/myvm-vnc.acl",
148+
"refresh": true
149+
}
150+
}
151+
}
152+
153+
154+
If ``refresh`` is ``yes``, inotify is used to monitor for changes
155+
to the file and auto-reload the rules.
156+
157+
The ``myvm-vnc.acl`` file should contain the match rules in a format that
158+
closely matches the previous driver:
159+
160+
::
161+
162+
{
163+
"rules": [
164+
{ "match": "fred", "policy": "allow", "format": "exact" },
165+
{ "match": "bob", "policy": "allow", "format": "exact" },
166+
{ "match": "danb", "policy": "deny", "format": "exact" },
167+
{ "match": "dan*", "policy": "allow", "format": "glob" }
168+
],
169+
"policy": "deny"
170+
}
171+
172+
173+
The object can be created on the command line using
174+
175+
::
176+
177+
-object authz-list-file,id=authz0,\
178+
filename=/etc/qemu/myvm-vnc.acl,refresh=on
179+
180+
181+
PAM
182+
^^^
183+
184+
In some scenarios it might be desirable to integrate with authorization
185+
mechanisms that are implemented outside of QEMU. In order to allow maximum
186+
flexibility, QEMU provides a driver that uses the ``PAM`` framework.
187+
188+
To create an instance of this class via QMP:
189+
190+
::
191+
192+
{
193+
"execute": "object-add",
194+
"arguments": {
195+
"qom-type": "authz-pam",
196+
"id": "authz0",
197+
"parameters": {
198+
"service": "qemu-vnc-tls"
199+
}
200+
}
201+
}
202+
203+
204+
The driver only uses the PAM "account" verification
205+
subsystem. The above config would require a config
206+
file /etc/pam.d/qemu-vnc-tls. For a simple file
207+
lookup it would contain
208+
209+
::
210+
211+
account requisite pam_listfile.so item=user sense=allow \
212+
file=/etc/qemu/vnc.allow
213+
214+
215+
The external file would then contain a list of usernames.
216+
If x509 cert was being used as the username, a suitable
217+
entry would match the distinguished name:
218+
219+
::
220+
221+
CN=laptop.berrange.com,O=Berrange Home,L=London,ST=London,C=GB
222+
223+
224+
On the command line it can be created using
225+
226+
::
227+
228+
-object authz-pam,id=authz0,service=qemu-vnc-tls
229+
230+
231+
There are a variety of PAM plugins that can be used which are not illustrated
232+
here, and it is possible to implement brand new plugins using the PAM API.
233+
234+
235+
Connecting backends
236+
~~~~~~~~~~~~~~~~~~~
237+
238+
The authorization driver is created using the ``-object`` argument and then
239+
needs to be associated with a network service. The authorization driver object
240+
will be given a unique ID that needs to be referenced.
241+
242+
The property to set in the network service will vary depending on the type of
243+
identity to verify. By convention, any network server backend that uses TLS
244+
will provide ``tls-authz`` property, while any server using SASL will provide
245+
a ``sasl-authz`` property.
246+
247+
Thus an example using SASL and authorization for the VNC server would look
248+
like:
249+
250+
::
251+
252+
$QEMU --object authz-simple,id=authz0,identity=fred \
253+
--vnc 0.0.0.0:1,sasl,sasl-authz=authz0
254+
255+
While to validate both the x509 certificate and SASL username:
256+
257+
::
258+
259+
echo "CN=laptop.qemu.org,O=QEMU Project,L=London,ST=London,C=GB" >> tls.acl
260+
$QEMU --object authz-simple,id=authz0,identity=fred \
261+
--object authz-list-file,id=authz1,filename=tls.acl \
262+
--object tls-creds-x509,id=tls0,dir=/etc/qemu/tls,verify-peer=yes \
263+
--vnc 0.0.0.0:1,sasl,sasl-authz=auth0,tls-creds=tls0,tls-authz=authz1

docs/system/index.rst

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Contents:
3030
guest-loader
3131
vnc-security
3232
tls
33+
secrets
34+
authz
3335
gdb
3436
managed-startup
3537
cpu-hotplug

0 commit comments

Comments
 (0)