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 @@ - + - - + + + + + + + + + + + + +