diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c23dda673e..4435ee2ad4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7228,8 +7228,17 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
if (!(src->ssh_user = virXMLPropStringRequired(tmpnode, "username")))
return -1;
- if (!(src->ssh_keyfile = virXMLPropStringRequired(tmpnode, "keyfile")))
+ /* optional path to an ssh key file */
+ src->ssh_keyfile = virXMLPropString(tmpnode, "keyfile");
+
+ /* optional ssh-agent socket location */
+ src->ssh_agent = virXMLPropString(tmpnode, "agentsock");
+ if (!src->ssh_keyfile && !src->ssh_agent) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("element '%1$s' requires either 'keyfile' or 'agentsock' attribute"),
+ tmpnode->name);
return -1;
+ }
}
}
@@ -22222,11 +22231,12 @@ virDomainDiskSourceFormatNetwork(virBuffer *attrBuf,
if (src->protocol == VIR_STORAGE_NET_PROTOCOL_SSH) {
if (src->ssh_known_hosts_file)
virBufferEscapeString(childBuf, "\n", src->ssh_known_hosts_file);
- if (src->ssh_keyfile) {
+ if (src->ssh_keyfile || src->ssh_agent) {
virBufferAddLit(childBuf, "ssh_user);
virBufferEscapeString(childBuf, " keyfile='%s'", src->ssh_keyfile);
+ virBufferEscapeString(childBuf, " agentsock='%s'", src->ssh_agent);
virBufferAddLit(childBuf, "/>\n");
}
diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c
index 67d50af074..61a433ab1f 100644
--- a/src/conf/storage_source_conf.c
+++ b/src/conf/storage_source_conf.c
@@ -899,6 +899,7 @@ virStorageSourceCopy(const virStorageSource *src,
def->ssh_user = g_strdup(src->ssh_user);
def->ssh_known_hosts_file = g_strdup(src->ssh_known_hosts_file);
def->ssh_keyfile = g_strdup(src->ssh_keyfile);
+ def->ssh_agent = g_strdup(src->ssh_agent);
def->nfs_user = g_strdup(src->nfs_user);
def->nfs_group = g_strdup(src->nfs_group);
@@ -1179,6 +1180,7 @@ virStorageSourceClear(virStorageSource *def)
VIR_FREE(def->ssh_user);
VIR_FREE(def->ssh_known_hosts_file);
VIR_FREE(def->ssh_keyfile);
+ VIR_FREE(def->ssh_agent);
VIR_FREE(def->nfs_user);
VIR_FREE(def->nfs_group);
diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h
index 3b6e628e21..fc6c67f426 100644
--- a/src/conf/storage_source_conf.h
+++ b/src/conf/storage_source_conf.h
@@ -413,6 +413,7 @@ struct _virStorageSource {
bool ssh_host_key_check_disabled;
char *ssh_known_hosts_file;
char *ssh_keyfile;
+ char *ssh_agent;
/* nfs_user and nfs_group store the strings passed in by the user for NFS params.
* nfs_uid and nfs_gid represent the converted/looked up ID numbers which are used
diff --git a/src/qemu/qemu_nbdkit.c b/src/qemu/qemu_nbdkit.c
index 0a6c7962b0..66b09cd240 100644
--- a/src/qemu/qemu_nbdkit.c
+++ b/src/qemu/qemu_nbdkit.c
@@ -1057,6 +1057,9 @@ qemuNbdkitProcessBuildCommandSSH(qemuNbdkitProcess *proc,
virCommandAddArgPair(cmd, "user", proc->source->ssh_user);
}
+ if (proc->source->ssh_agent)
+ virCommandAddEnvPair(cmd, "SSH_AUTH_SOCK", proc->source->ssh_agent);
+
if (proc->source->ssh_host_key_check_disabled)
virCommandAddArgPair(cmd, "verify-remote-host", "false");
@@ -1179,6 +1182,10 @@ qemuNbdkitProcessStart(qemuNbdkitProcess *proc,
qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_keyfile, false) < 0)
goto error;
+ if (proc->source->ssh_agent &&
+ qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_agent, false) < 0)
+ goto error;
+
if (proc->source->ssh_known_hosts_file &&
qemuSecurityDomainSetPathLabel(driver, vm, proc->source->ssh_known_hosts_file, false) < 0)
goto error;
@@ -1267,6 +1274,9 @@ qemuNbdkitProcessStop(qemuNbdkitProcess *proc,
if (proc->source->ssh_keyfile)
qemuSecurityDomainRestorePathLabel(driver, vm, proc->source->ssh_keyfile);
+ if (proc->source->ssh_agent)
+ qemuSecurityDomainRestorePathLabel(driver, vm, proc->source->ssh_agent);
+
if (proc->pid < 0)
return 0;
diff --git a/tests/qemunbdkitdata/disk-network-ssh-key.args.disk0 b/tests/qemunbdkitdata/disk-network-ssh-key.args.disk0
index 0b52bfe0fb..f627700490 100644
--- a/tests/qemunbdkitdata/disk-network-ssh-key.args.disk0
+++ b/tests/qemunbdkitdata/disk-network-ssh-key.args.disk0
@@ -1,9 +1,9 @@
+SSH_AUTH_SOCK=/path/to/agent/socket \
nbdkit \
--unix /tmp/statedir-0/nbdkit-test-disk-0.socket \
--foreground ssh \
host=example.org \
port=2222 \
-path=test.img \
-identity=/path/to/id_rsa \
+path=test1.img \
user=myuser \
-known-hosts=/path/to/ssh_known_hosts
+known-hosts=/path/to/ssh_known_hosts1
diff --git a/tests/qemunbdkitdata/disk-network-ssh-key.args.disk1 b/tests/qemunbdkitdata/disk-network-ssh-key.args.disk1
new file mode 100644
index 0000000000..80df9c30c6
--- /dev/null
+++ b/tests/qemunbdkitdata/disk-network-ssh-key.args.disk1
@@ -0,0 +1,9 @@
+nbdkit \
+--unix /tmp/statedir-1/nbdkit-test-disk-1.socket \
+--foreground ssh \
+host=example.org \
+port=2222 \
+path=test2.img \
+identity=/path/to/id_rsa \
+user=myuser2 \
+known-hosts=/path/to/ssh_known_hosts2
diff --git a/tests/qemuxml2argvdata/disk-network-ssh-key.xml b/tests/qemuxml2argvdata/disk-network-ssh-key.xml
index 81b92231fa..fda01e7e68 100644
--- a/tests/qemuxml2argvdata/disk-network-ssh-key.xml
+++ b/tests/qemuxml2argvdata/disk-network-ssh-key.xml
@@ -15,12 +15,23 @@
-
+
+
+
+
+
+
+
+