Skip to content

Commit

Permalink
migration: add support for a "tls-authz" migration parameter
Browse files Browse the repository at this point in the history
The QEMU instance that runs as the server for the migration data
transport (ie the target QEMU) needs to be able to configure access
control so it can prevent unauthorized clients initiating an incoming
migration. This adds a new 'tls-authz' migration parameter that is used
to provide the QOM ID of a QAuthZ subclass instance that provides the
access control check. This is checked against the x509 certificate
obtained during the TLS handshake.

For example, when starting a QEMU for incoming migration, it is
possible to give an example identity of the source QEMU that is
intended to be connecting later:

  $QEMU \
     -monitor stdio \
     -incoming defer \
     ...other args...

  (qemu) object_add tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\
             endpoint=server,verify-peer=yes \
  (qemu) object_add authz-simple,id=auth0,identity=CN=laptop.example.com,,\
             O=Example Org,,L=London,,ST=London,,C=GB \
  (qemu) migrate_incoming tcp:localhost:9000

Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
  • Loading branch information
berrange authored and Juan Quintela committed Mar 25, 2019
1 parent cbfd6c9 commit d2f1d29
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
9 changes: 9 additions & 0 deletions hmp.c
Expand Up @@ -441,6 +441,9 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "%s: %" PRIu64 "\n",
MigrationParameter_str(MIGRATION_PARAMETER_MAX_POSTCOPY_BANDWIDTH),
params->max_postcopy_bandwidth);
monitor_printf(mon, " %s: '%s'\n",
MigrationParameter_str(MIGRATION_PARAMETER_TLS_AUTHZ),
params->has_tls_authz ? params->tls_authz : "");
}

qapi_free_MigrationParameters(params);
Expand Down Expand Up @@ -1783,6 +1786,12 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
p->tls_hostname->type = QTYPE_QSTRING;
visit_type_str(v, param, &p->tls_hostname->u.s, &err);
break;
case MIGRATION_PARAMETER_TLS_AUTHZ:
p->has_tls_authz = true;
p->tls_authz = g_new0(StrOrNull, 1);
p->tls_authz->type = QTYPE_QSTRING;
visit_type_str(v, param, &p->tls_authz->u.s, &err);
break;
case MIGRATION_PARAMETER_MAX_BANDWIDTH:
p->has_max_bandwidth = true;
/*
Expand Down
8 changes: 8 additions & 0 deletions migration/migration.c
Expand Up @@ -757,6 +757,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
params->tls_creds = g_strdup(s->parameters.tls_creds);
params->has_tls_hostname = true;
params->tls_hostname = g_strdup(s->parameters.tls_hostname);
params->has_tls_authz = true;
params->tls_authz = g_strdup(s->parameters.tls_authz);
params->has_max_bandwidth = true;
params->max_bandwidth = s->parameters.max_bandwidth;
params->has_downtime_limit = true;
Expand Down Expand Up @@ -1331,6 +1333,12 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
s->parameters.tls_hostname = g_strdup(params->tls_hostname->u.s);
}

if (params->has_tls_authz) {
g_free(s->parameters.tls_authz);
assert(params->tls_authz->type == QTYPE_QSTRING);
s->parameters.tls_authz = g_strdup(params->tls_authz->u.s);
}

if (params->has_max_bandwidth) {
s->parameters.max_bandwidth = params->max_bandwidth;
if (s->to_dst_file) {
Expand Down
2 changes: 1 addition & 1 deletion migration/tls.c
Expand Up @@ -94,7 +94,7 @@ void migration_tls_channel_process_incoming(MigrationState *s,

tioc = qio_channel_tls_new_server(
ioc, creds,
NULL, /* XXX pass ACL name */
s->parameters.tls_authz,
errp);
if (!tioc) {
return;
Expand Down
14 changes: 13 additions & 1 deletion qapi/migration.json
Expand Up @@ -541,6 +541,12 @@
# hostname must be provided so that the server's x509
# certificate identity can be validated. (Since 2.7)
#
# @tls-authz: ID of the 'authz' object subclass that provides access control
# checking of the TLS x509 certificate distinguished name.
# This object is only resolved at time of use, so can be deleted
# and recreated on the fly while the migration server is active.
# If missing, it will default to denying access (Since 4.0)
#
# @max-bandwidth: to set maximum speed for migration. maximum speed in
# bytes per second. (Since 2.8)
#
Expand Down Expand Up @@ -582,7 +588,7 @@
'compress-level', 'compress-threads', 'decompress-threads',
'compress-wait-thread',
'cpu-throttle-initial', 'cpu-throttle-increment',
'tls-creds', 'tls-hostname', 'max-bandwidth',
'tls-creds', 'tls-hostname', 'tls-authz', 'max-bandwidth',
'downtime-limit', 'x-checkpoint-delay', 'block-incremental',
'multifd-channels',
'xbzrle-cache-size', 'max-postcopy-bandwidth',
Expand Down Expand Up @@ -693,6 +699,7 @@
'*cpu-throttle-increment': 'int',
'*tls-creds': 'StrOrNull',
'*tls-hostname': 'StrOrNull',
'*tls-authz': 'StrOrNull',
'*max-bandwidth': 'int',
'*downtime-limit': 'int',
'*x-checkpoint-delay': 'int',
Expand Down Expand Up @@ -773,6 +780,10 @@
# associated with the migration URI, if any. (Since 2.9)
# Note: 2.8 reports this by omitting tls-hostname instead.
#
# @tls-authz: ID of the 'authz' object subclass that provides access control
# checking of the TLS x509 certificate distinguished name. (Since
# 4.0)
#
# @max-bandwidth: to set maximum speed for migration. maximum speed in
# bytes per second. (Since 2.8)
#
Expand Down Expand Up @@ -821,6 +832,7 @@
'*cpu-throttle-increment': 'uint8',
'*tls-creds': 'str',
'*tls-hostname': 'str',
'*tls-authz': 'str',
'*max-bandwidth': 'size',
'*downtime-limit': 'uint64',
'*x-checkpoint-delay': 'uint32',
Expand Down

0 comments on commit d2f1d29

Please sign in to comment.