Since both APIs accept/return an array of strings we can't have
client/server dispatch code generated. But implementation is
fairly trivial, although verbose.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/remote/remote_daemon_dispatch.c | 82 +++++++++++++++++++++++++++
src/remote/remote_driver.c | 87 +++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 34 ++++++++++-
src/remote_protocol-structs | 22 ++++++++
4 files changed, 224 insertions(+), 1 deletion(-)
diff --git a/src/remote/remote_daemon_dispatch.c b/src/remote/remote_daemon_dispatch.c
index eb5f6ebb0c..46683aa4a7 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -7381,3 +7381,85 @@ remoteDispatchDomainGetGuestInfo(virNetServerPtr server
G_GNUC_UNUSED,
return rv;
}
+
+static int
+remoteDispatchDomainAuthorizedSshKeysGet(virNetServerPtr server G_GNUC_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg G_GNUC_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_domain_authorized_ssh_keys_get_args
*args,
+ remote_domain_authorized_ssh_keys_get_ret *ret)
+{
+ int rv = -1;
+ virConnectPtr conn = remoteGetHypervisorConn(client);
+ int nkeys = 0;
+ char **keys = NULL;
+ virDomainPtr dom = NULL;
+
+ if (!conn)
+ goto cleanup;
+
+ if (!(dom = get_nonnull_domain(conn, args->dom)))
+ goto cleanup;
+
+ if ((nkeys = virDomainAuthorizedSSHKeysGet(dom, args->user,
+ &keys, args->flags)) < 0)
+ goto cleanup;
+
+ if (nkeys > REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Number of keys %d, which exceeds max liit: %d"),
+ nkeys, REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX);
+ goto cleanup;
+ }
+
+ ret->keys.keys_val = g_steal_pointer(&keys);
+ ret->keys.keys_len = nkeys;
+
+ rv = nkeys;
+
+ cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (nkeys > 0)
+ virStringListFreeCount(keys, nkeys);
+ virObjectUnref(dom);
+
+ return rv;
+}
+
+static int
+remoteDispatchDomainAuthorizedSshKeysSet(virNetServerPtr server G_GNUC_UNUSED,
+ virNetServerClientPtr client,
+ virNetMessagePtr msg G_GNUC_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_domain_authorized_ssh_keys_set_args
*args)
+{
+ int rv = -1;
+ virConnectPtr conn = remoteGetHypervisorConn(client);
+ virDomainPtr dom = NULL;
+
+ if (!conn)
+ goto cleanup;
+
+ if (!(dom = get_nonnull_domain(conn, args->dom)))
+ goto cleanup;
+
+ if (args->keys.keys_len > REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Number of keys %d, which exceeds max liit: %d"),
+ args->keys.keys_len, REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX);
+ goto cleanup;
+ }
+
+ rv = virDomainAuthorizedSSHKeysSet(dom, args->user,
+ (const char **) args->keys.keys_val,
+ args->keys.keys_len, args->flags);
+
+ cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ virObjectUnref(dom);
+
+ return rv;
+}
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 9cd2fd36ae..0b8d1e753f 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8027,6 +8027,91 @@ remoteDomainGetGuestInfo(virDomainPtr dom,
return rv;
}
+static int
+remoteDomainAuthorizedSSHKeysGet(virDomainPtr domain,
+ const char *user,
+ char ***keys,
+ unsigned int flags)
+{
+ int rv = -1;
+ size_t i;
+ struct private_data *priv = domain->conn->privateData;
+ remote_domain_authorized_ssh_keys_get_args args;
+ remote_domain_authorized_ssh_keys_get_ret ret;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain(&args.dom, domain);
+ args.user = (char *) user;
+ args.flags = flags;
+ memset(&ret, 0, sizeof(ret));
+
+ if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_GET,
+ (xdrproc_t) xdr_remote_domain_authorized_ssh_keys_get_args, (char
*)&args,
+ (xdrproc_t) xdr_remote_domain_authorized_ssh_keys_get_ret, (char *)&ret)
== -1) {
+ goto cleanup;
+ }
+
+ if (ret.keys.keys_len > REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX) {
+ virReportError(VIR_ERR_RPC, "%s",
+ _("remoteDomainAuthorizedSSHKeysGet: "
+ "returned number of keys exceeds limit"));
+ goto cleanup;
+ }
+
+ *keys = g_new0(char *, ret.keys.keys_len);
+ for (i = 0; i < ret.keys.keys_len; i++)
+ (*keys)[i] = g_strdup(ret.keys.keys_val[i]);
+
+ rv = ret.keys.keys_len;
+
+ cleanup:
+ remoteDriverUnlock(priv);
+ xdr_free((xdrproc_t)xdr_remote_domain_authorized_ssh_keys_get_ret,
+ (char *) &ret);
+ return rv;
+}
+
+static int
+remoteDomainAuthorizedSSHKeysSet(virDomainPtr domain,
+ const char *user,
+ const char **keys,
+ int nkeys,
+ unsigned int flags)
+{
+ int rv = -1;
+ struct private_data *priv = domain->conn->privateData;
+ remote_domain_authorized_ssh_keys_set_args args;
+
+ remoteDriverLock(priv);
+
+ if (nkeys > REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX) {
+ virReportError(VIR_ERR_RPC, "%s",
+ _("remoteDomainAuthorizedSSHKeysSet: "
+ "returned number of keys exceeds limit"));
+ goto cleanup;
+ }
+
+ make_nonnull_domain(&args.dom, domain);
+ args.user = (char *) user;
+ args.keys.keys_len = nkeys;
+ args.keys.keys_val = (char **) keys;
+ args.flags = flags;
+
+ if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET,
+ (xdrproc_t) xdr_remote_domain_authorized_ssh_keys_set_args, (char
*)&args,
+ (xdrproc_t) xdr_void, (char *) NULL) == -1) {
+ goto cleanup;
+ }
+
+ rv = 0;
+
+ cleanup:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
+
/* get_nonnull_domain and get_nonnull_network turn an on-wire
* (name, uuid) pair into virDomainPtr or virNetworkPtr object.
* These can return NULL if underlying memory allocations fail,
@@ -8458,6 +8543,8 @@ static virHypervisorDriver hypervisor_driver = {
.domainAgentSetResponseTimeout = remoteDomainAgentSetResponseTimeout, /* 5.10.0 */
.domainBackupBegin = remoteDomainBackupBegin, /* 6.0.0 */
.domainBackupGetXMLDesc = remoteDomainBackupGetXMLDesc, /* 6.0.0 */
+ .domainAuthorizedSSHKeysGet = remoteDomainAuthorizedSSHKeysGet, /* 6.10.0 */
+ .domainAuthorizedSSHKeysSet = remoteDomainAuthorizedSSHKeysSet, /* 6.10.0 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 5e5e781e76..89ecc832ff 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -280,6 +280,9 @@ const REMOTE_DOMAIN_GUEST_INFO_PARAMS_MAX = 2048;
*/
const REMOTE_NETWORK_PORT_PARAMETERS_MAX = 16;
+/* Upper limit on number of SSH keys */
+const REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX = 2048;
+
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@@ -3779,6 +3782,23 @@ struct remote_domain_backup_get_xml_desc_ret {
remote_nonnull_string xml;
};
+struct remote_domain_authorized_ssh_keys_get_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string user;
+ unsigned int flags;
+};
+
+struct remote_domain_authorized_ssh_keys_get_ret {
+ remote_nonnull_string keys<REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX>;
+};
+
+struct remote_domain_authorized_ssh_keys_set_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string user;
+ remote_nonnull_string keys<REMOTE_DOMAIN_AUTHORIZED_SSH_KEYS_MAX>;
+ unsigned int flags;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -6682,5 +6702,17 @@ enum remote_procedure {
* @generate: both
* @acl: none
*/
- REMOTE_PROC_DOMAIN_EVENT_MEMORY_FAILURE = 423
+ REMOTE_PROC_DOMAIN_EVENT_MEMORY_FAILURE = 423,
+
+ /**
+ * @generate: none
+ * @acl: domain:read
+ */
+ REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_GET = 424,
+
+ /**
+ * @generate: none
+ * @acl: domain:write
+ */
+ REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index c2ae411885..9bcd14603d 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -3142,6 +3142,26 @@ struct remote_domain_backup_get_xml_desc_args {
struct remote_domain_backup_get_xml_desc_ret {
remote_nonnull_string xml;
};
+struct remote_domain_authorized_ssh_keys_get_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string user;
+ u_int flags;
+};
+struct remote_domain_authorized_ssh_keys_get_ret {
+ struct {
+ u_int keys_len;
+ remote_nonnull_string * keys_val;
+ } keys;
+};
+struct remote_domain_authorized_ssh_keys_set_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string user;
+ struct {
+ u_int keys_len;
+ remote_nonnull_string * keys_val;
+ } keys;
+ u_int flags;
+};
enum remote_procedure {
REMOTE_PROC_CONNECT_OPEN = 1,
REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3566,4 +3586,6 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_BACKUP_BEGIN = 421,
REMOTE_PROC_DOMAIN_BACKUP_GET_XML_DESC = 422,
REMOTE_PROC_DOMAIN_EVENT_MEMORY_FAILURE = 423,
+ REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_GET = 424,
+ REMOTE_PROC_DOMAIN_AUTHORIZED_SSH_KEYS_SET = 425,
};
--
2.26.2