5d360b
From 1f5e04965db81bea1eac402110166290bfc774db Mon Sep 17 00:00:00 2001
5d360b
From: Jeffrey Cody <jcody@redhat.com>
5d360b
Date: Sun, 1 Oct 2017 03:55:19 +0200
5d360b
Subject: [PATCH 4/4] block/ssh: Use QemuOpts for runtime options
5d360b
5d360b
RH-Author: Jeffrey Cody <jcody@redhat.com>
5d360b
Message-id: <798f4a5f4498382bd5764a5e7889595a36aab78c.1506829990.git.jcody@redhat.com>
5d360b
Patchwork-id: 76786
5d360b
O-Subject: [RHEL-7.5 1/1] block/ssh: Use QemuOpts for runtime options
5d360b
Bugzilla: 1461672
5d360b
RH-Acked-by: Thomas Huth <thuth@redhat.com>
5d360b
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
5d360b
RH-Acked-by: Max Reitz <mreitz@redhat.com>
5d360b
5d360b
From: Max Reitz <mreitz@redhat.com>
5d360b
5d360b
Using QemuOpts will prevent qemu from crashing if the input options have
5d360b
not been validated (which is the case when they are specified on the
5d360b
command line or in a json: filename) and some have the wrong type.
5d360b
5d360b
Signed-off-by: Max Reitz <mreitz@redhat.com>
5d360b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
5d360b
(cherry picked from commit 8a6a80896d6af03b8ee0c17cdf37219eca2588a7)
5d360b
Signed-off-by: Jeff Cody <jcody@redhat.com>
5d360b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
5d360b
---
5d360b
 block/ssh.c | 79 ++++++++++++++++++++++++++++++++++++++++++-------------------
5d360b
 1 file changed, 55 insertions(+), 24 deletions(-)
5d360b
5d360b
diff --git a/block/ssh.c b/block/ssh.c
5d360b
index b00ff7f..a9341b8 100644
5d360b
--- a/block/ssh.c
5d360b
+++ b/block/ssh.c
5d360b
@@ -510,36 +510,73 @@ static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
5d360b
     return ret;
5d360b
 }
5d360b
 
5d360b
+static QemuOptsList ssh_runtime_opts = {
5d360b
+    .name = "ssh",
5d360b
+    .head = QTAILQ_HEAD_INITIALIZER(ssh_runtime_opts.head),
5d360b
+    .desc = {
5d360b
+        {
5d360b
+            .name = "host",
5d360b
+            .type = QEMU_OPT_STRING,
5d360b
+            .help = "Host to connect to",
5d360b
+        },
5d360b
+        {
5d360b
+            .name = "port",
5d360b
+            .type = QEMU_OPT_NUMBER,
5d360b
+            .help = "Port to connect to",
5d360b
+        },
5d360b
+        {
5d360b
+            .name = "path",
5d360b
+            .type = QEMU_OPT_STRING,
5d360b
+            .help = "Path of the image on the host",
5d360b
+        },
5d360b
+        {
5d360b
+            .name = "user",
5d360b
+            .type = QEMU_OPT_STRING,
5d360b
+            .help = "User as which to connect",
5d360b
+        },
5d360b
+        {
5d360b
+            .name = "host_key_check",
5d360b
+            .type = QEMU_OPT_STRING,
5d360b
+            .help = "Defines how and what to check the host key against",
5d360b
+        },
5d360b
+    },
5d360b
+};
5d360b
+
5d360b
 static int connect_to_ssh(BDRVSSHState *s, QDict *options,
5d360b
                           int ssh_flags, int creat_mode, Error **errp)
5d360b
 {
5d360b
     int r, ret;
5d360b
+    QemuOpts *opts = NULL;
5d360b
+    Error *local_err = NULL;
5d360b
     const char *host, *user, *path, *host_key_check;
5d360b
     int port;
5d360b
 
5d360b
-    if (!qdict_haskey(options, "host")) {
5d360b
+    opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort);
5d360b
+    qemu_opts_absorb_qdict(opts, options, &local_err);
5d360b
+    if (local_err) {
5d360b
         ret = -EINVAL;
5d360b
-        error_setg(errp, "No hostname was specified");
5d360b
+        error_propagate(errp, local_err);
5d360b
         goto err;
5d360b
     }
5d360b
-    host = qdict_get_str(options, "host");
5d360b
 
5d360b
-    if (qdict_haskey(options, "port")) {
5d360b
-        port = qdict_get_int(options, "port");
5d360b
-    } else {
5d360b
-        port = 22;
5d360b
+    host = qemu_opt_get(opts, "host");
5d360b
+    if (!host) {
5d360b
+        ret = -EINVAL;
5d360b
+        error_setg(errp, "No hostname was specified");
5d360b
+        goto err;
5d360b
     }
5d360b
 
5d360b
-    if (!qdict_haskey(options, "path")) {
5d360b
+    port = qemu_opt_get_number(opts, "port", 22);
5d360b
+
5d360b
+    path = qemu_opt_get(opts, "path");
5d360b
+    if (!path) {
5d360b
         ret = -EINVAL;
5d360b
         error_setg(errp, "No path was specified");
5d360b
         goto err;
5d360b
     }
5d360b
-    path = qdict_get_str(options, "path");
5d360b
 
5d360b
-    if (qdict_haskey(options, "user")) {
5d360b
-        user = qdict_get_str(options, "user");
5d360b
-    } else {
5d360b
+    user = qemu_opt_get(opts, "user");
5d360b
+    if (!user) {
5d360b
         user = g_get_user_name();
5d360b
         if (!user) {
5d360b
             error_setg_errno(errp, errno, "Can't get user name");
5d360b
@@ -548,9 +585,8 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
5d360b
         }
5d360b
     }
5d360b
 
5d360b
-    if (qdict_haskey(options, "host_key_check")) {
5d360b
-        host_key_check = qdict_get_str(options, "host_key_check");
5d360b
-    } else {
5d360b
+    host_key_check = qemu_opt_get(opts, "host_key_check");
5d360b
+    if (!host_key_check) {
5d360b
         host_key_check = "yes";
5d360b
     }
5d360b
 
5d360b
@@ -614,21 +650,14 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
5d360b
         goto err;
5d360b
     }
5d360b
 
5d360b
+    qemu_opts_del(opts);
5d360b
+
5d360b
     r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs);
5d360b
     if (r < 0) {
5d360b
         sftp_error_setg(errp, s, "failed to read file attributes");
5d360b
         return -EINVAL;
5d360b
     }
5d360b
 
5d360b
-    /* Delete the options we've used; any not deleted will cause the
5d360b
-     * block layer to give an error about unused options.
5d360b
-     */
5d360b
-    qdict_del(options, "host");
5d360b
-    qdict_del(options, "port");
5d360b
-    qdict_del(options, "user");
5d360b
-    qdict_del(options, "path");
5d360b
-    qdict_del(options, "host_key_check");
5d360b
-
5d360b
     return 0;
5d360b
 
5d360b
  err:
5d360b
@@ -648,6 +677,8 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
5d360b
     }
5d360b
     s->session = NULL;
5d360b
 
5d360b
+    qemu_opts_del(opts);
5d360b
+
5d360b
     return ret;
5d360b
 }
5d360b
 
5d360b
-- 
5d360b
1.8.3.1
5d360b