Changes since the second submission: - Update for the changed public API - s/secret_id/uuid/g - use "unsigned char *" for secret value --- src/datatypes.h | 1 + src/remote_internal.c | 323 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 324 insertions(+), 0 deletions(-) diff --git a/src/datatypes.h b/src/datatypes.h index 56c3777..aa60b63 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -140,6 +140,7 @@ struct _virConnect { void * interfacePrivateData; void * storagePrivateData; void * devMonPrivateData; + void * secretPrivateData; /* * The lock mutex must be acquired before accessing/changing diff --git a/src/remote_internal.c b/src/remote_internal.c index a58b768..d661fe2 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -221,11 +221,13 @@ static virInterfacePtr get_nonnull_interface (virConnectPtr conn, remote_nonnull static virStoragePoolPtr get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool); static virStorageVolPtr get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol); static virNodeDevicePtr get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev); +static virSecretPtr get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret); static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src); static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src); static void make_nonnull_interface (remote_nonnull_interface *interface_dst, virInterfacePtr interface_src); static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src); static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src); +static void make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src); void remoteDomainEventFired(int watch, int fd, int event, void *data); static void remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr); void remoteDomainEventQueueFlush(int timer, void *opaque); @@ -6319,6 +6321,300 @@ done: return rv; } +static virDrvOpenStatus +remoteSecretOpen (virConnectPtr conn, + virConnectAuthPtr auth, + int flags) +{ + if (inside_daemon) + return VIR_DRV_OPEN_DECLINED; + + if (conn && + conn->driver && + STREQ (conn->driver->name, "remote")) { + struct private_data *priv; + + /* If we're here, the remote driver is already + * in use due to a) a QEMU uri, or b) a remote + * URI. So we can re-use existing connection + */ + priv = conn->privateData; + remoteDriverLock(priv); + priv->localUses++; + conn->secretPrivateData = priv; + remoteDriverUnlock(priv); + return VIR_DRV_OPEN_SUCCESS; + } else if (conn->networkDriver && + STREQ (conn->networkDriver->name, "remote")) { + struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + conn->secretPrivateData = priv; + priv->localUses++; + remoteDriverUnlock(priv); + return VIR_DRV_OPEN_SUCCESS; + } else { + /* Using a non-remote driver, so we need to open a + * new connection for secret APIs, forcing it to + * use the UNIX transport. + */ + struct private_data *priv; + int ret; + ret = remoteOpenSecondaryDriver(conn, + auth, + flags, + &priv); + if (ret == VIR_DRV_OPEN_SUCCESS) + conn->secretPrivateData = priv; + return ret; + } +} + +static int +remoteSecretClose (virConnectPtr conn) +{ + int rv = 0; + struct private_data *priv = conn->secretPrivateData; + + conn->secretPrivateData = NULL; + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + rv = doRemoteClose(conn, priv); + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE(priv); + } + if (priv) + remoteDriverUnlock(priv); + return rv; +} + +static int +remoteSecretNumOfSecrets (virConnectPtr conn) +{ + int rv = -1; + remote_num_of_secrets_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_SECRETS, + (xdrproc_t) xdr_void, (char *) NULL, + (xdrproc_t) xdr_remote_num_of_secrets_ret, (char *) &ret) == -1) + goto done; + + rv = ret.num; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretListSecrets (virConnectPtr conn, char **uuids, int maxuuids) +{ + int rv = -1; + int i; + remote_list_secrets_args args; + remote_list_secrets_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock(priv); + + if (maxuuids > REMOTE_SECRET_UUID_LIST_MAX) { + errorf (conn, VIR_ERR_RPC, _("too many remote secret UUIDs: %d > %d"), + maxuuids, REMOTE_SECRET_UUID_LIST_MAX); + goto done; + } + args.maxuuids = maxuuids; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_LIST_SECRETS, + (xdrproc_t) xdr_remote_list_secrets_args, (char *) &args, + (xdrproc_t) xdr_remote_list_secrets_ret, (char *) &ret) == -1) + goto done; + + if (ret.uuids.uuids_len > maxuuids) { + errorf (conn, VIR_ERR_RPC, _("too many remote secret UUIDs: %d > %d"), + ret.uuids.uuids_len, maxuuids); + goto cleanup; + } + + /* This call is caller-frees. However xdr_free will free up both the + * names and the list of pointers, so we have to strdup the + * names here. + */ + for (i = 0; i < ret.uuids.uuids_len; ++i) + uuids[i] = strdup (ret.uuids.uuids_val[i]); + + rv = ret.uuids.uuids_len; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_list_secrets_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + +static virSecretPtr +remoteSecretLookupByUUIDString (virConnectPtr conn, const char *uuid) +{ + virSecretPtr rv = NULL; + remote_secret_lookup_by_uuid_string_args args; + remote_secret_lookup_by_uuid_string_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.uuid = (char *) uuid; + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING, + (xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, (char *) &ret) == -1) + goto done; + + rv = get_nonnull_secret (conn, ret.secret); + xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, + (char *) &ret); + +done: + remoteDriverUnlock (priv); + return rv; +} + +static virSecretPtr +remoteSecretDefineXML (virConnectPtr conn, const char *xml) +{ + virSecretPtr rv = NULL; + remote_secret_define_xml_args args; + remote_secret_lookup_by_uuid_string_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.xml = (char *) xml; + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_DEFINE_XML, + (xdrproc_t) xdr_remote_secret_define_xml_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_define_xml_ret, (char *) &ret) == -1) + goto done; + + rv = get_nonnull_secret (conn, ret.secret); + xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, + (char *) &ret); + +done: + remoteDriverUnlock (priv); + return rv; +} + +static char * +remoteSecretGetXMLDesc (virSecretPtr secret) +{ + char *rv = NULL; + remote_secret_get_xml_desc_args args; + remote_secret_get_xml_desc_ret ret; + struct private_data *priv = secret->conn->secretPrivateData; + + remoteDriverLock (priv); + + make_nonnull_secret (&args.secret, secret); + + memset (&ret, 0, sizeof (ret)); + if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_XML_DESC, + (xdrproc_t) xdr_remote_secret_get_xml_desc_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_get_xml_desc_ret, (char *) &ret) == -1) + goto done; + + /* Caller frees. */ + rv = ret.xml; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretSetValue (virSecretPtr secret, const unsigned char *value, + size_t value_size) +{ + int rv = -1; + remote_secret_set_value_args args; + struct private_data *priv = secret->conn->secretPrivateData; + + remoteDriverLock (priv); + + make_nonnull_secret (&args.secret, secret); + args.value.value_len = value_size; + args.value.value_val = (char *) value; + + if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_SET_VALUE, + (xdrproc_t) xdr_remote_secret_set_value_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static unsigned char * +remoteSecretGetValue (virSecretPtr secret, size_t *value_size, + /* If the call goes over a socket, it's not internal */ + bool libvirt_internal_call ATTRIBUTE_UNUSED) +{ + unsigned char *rv = NULL; + remote_secret_get_value_args args; + remote_secret_get_value_ret ret; + struct private_data *priv = secret->conn->secretPrivateData; + + remoteDriverLock (priv); + + make_nonnull_secret (&args.secret, secret); + + memset (&ret, 0, sizeof (ret)); + if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_VALUE, + (xdrproc_t) xdr_remote_secret_get_value_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_get_value_ret, (char *) &ret) == -1) + goto done; + + *value_size = ret.value.value_len; + rv = (unsigned char *) ret.value.value_val; /* Caller frees. */ + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretUndefine (virSecretPtr secret) +{ + int rv = -1; + remote_secret_undefine_args args; + struct private_data *priv = secret->conn->secretPrivateData; + + remoteDriverLock (priv); + + make_nonnull_secret (&args.secret, secret); + + if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_UNDEFINE, + (xdrproc_t) xdr_remote_secret_undefine_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock (priv); + return rv; +} + /*----------------------------------------------------------------------*/ @@ -7415,6 +7711,12 @@ get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev) return virGetNodeDevice(conn, dev.name); } +static virSecretPtr +get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret) +{ + return virGetSecret(conn, secret.uuid); +} + /* Make remote_nonnull_domain and remote_nonnull_network. */ static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src) @@ -7454,6 +7756,12 @@ make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_dst->key = vol_src->key; } +static void +make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src) +{ + secret_dst->uuid = secret_src->uuid; +} + /*----------------------------------------------------------------------*/ unsigned long remoteVersion(void) @@ -7607,6 +7915,20 @@ static virStorageDriver storage_driver = { .volGetPath = remoteStorageVolGetPath, }; +static virSecretDriver secret_driver = { + .name = "remote", + .open = remoteSecretOpen, + .close = remoteSecretClose, + .numOfSecrets = remoteSecretNumOfSecrets, + .listSecrets = remoteSecretListSecrets, + .lookupByUUIDString = remoteSecretLookupByUUIDString, + .defineXML = remoteSecretDefineXML, + .getXMLDesc = remoteSecretGetXMLDesc, + .setValue = remoteSecretSetValue, + .getValue = remoteSecretGetValue, + .undefine = remoteSecretUndefine +}; + static virDeviceMonitor dev_monitor = { .name = "remote", .open = remoteDevMonOpen, @@ -7644,6 +7966,7 @@ remoteRegister (void) if (virRegisterInterfaceDriver (&interface_driver) == -1) return -1; if (virRegisterStorageDriver (&storage_driver) == -1) return -1; if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1; + if (virRegisterSecretDriver (&secret_driver) == -1) return -1; #ifdef WITH_LIBVIRTD if (virRegisterStateDriver (&state_driver) == -1) return -1; #endif -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list