Skip to content

Commit

Permalink
block/ssh: Use QemuOpts for runtime options
Browse files Browse the repository at this point in the history
Using QemuOpts will prevent qemu from crashing if the input options have
not been validated (which is the case when they are specified on the
command line or in a json: filename) and some have the wrong type.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
XanClic authored and kevmw committed Aug 15, 2016
1 parent 6bbbb0a commit 8a6a808
Showing 1 changed file with 55 additions and 24 deletions.
79 changes: 55 additions & 24 deletions block/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,36 +508,73 @@ static int authenticate(BDRVSSHState *s, const char *user, Error **errp)
return ret;
}

static QemuOptsList ssh_runtime_opts = {
.name = "ssh",
.head = QTAILQ_HEAD_INITIALIZER(ssh_runtime_opts.head),
.desc = {
{
.name = "host",
.type = QEMU_OPT_STRING,
.help = "Host to connect to",
},
{
.name = "port",
.type = QEMU_OPT_NUMBER,
.help = "Port to connect to",
},
{
.name = "path",
.type = QEMU_OPT_STRING,
.help = "Path of the image on the host",
},
{
.name = "user",
.type = QEMU_OPT_STRING,
.help = "User as which to connect",
},
{
.name = "host_key_check",
.type = QEMU_OPT_STRING,
.help = "Defines how and what to check the host key against",
},
},
};

static int connect_to_ssh(BDRVSSHState *s, QDict *options,
int ssh_flags, int creat_mode, Error **errp)
{
int r, ret;
QemuOpts *opts = NULL;
Error *local_err = NULL;
const char *host, *user, *path, *host_key_check;
int port;

if (!qdict_haskey(options, "host")) {
opts = qemu_opts_create(&ssh_runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
ret = -EINVAL;
error_setg(errp, "No hostname was specified");
error_propagate(errp, local_err);
goto err;
}
host = qdict_get_str(options, "host");

if (qdict_haskey(options, "port")) {
port = qdict_get_int(options, "port");
} else {
port = 22;
host = qemu_opt_get(opts, "host");
if (!host) {
ret = -EINVAL;
error_setg(errp, "No hostname was specified");
goto err;
}

if (!qdict_haskey(options, "path")) {
port = qemu_opt_get_number(opts, "port", 22);

path = qemu_opt_get(opts, "path");
if (!path) {
ret = -EINVAL;
error_setg(errp, "No path was specified");
goto err;
}
path = qdict_get_str(options, "path");

if (qdict_haskey(options, "user")) {
user = qdict_get_str(options, "user");
} else {
user = qemu_opt_get(opts, "user");
if (!user) {
user = g_get_user_name();
if (!user) {
error_setg_errno(errp, errno, "Can't get user name");
Expand All @@ -546,9 +583,8 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
}
}

if (qdict_haskey(options, "host_key_check")) {
host_key_check = qdict_get_str(options, "host_key_check");
} else {
host_key_check = qemu_opt_get(opts, "host_key_check");
if (!host_key_check) {
host_key_check = "yes";
}

Expand Down Expand Up @@ -612,21 +648,14 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
goto err;
}

qemu_opts_del(opts);

r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs);
if (r < 0) {
sftp_error_setg(errp, s, "failed to read file attributes");
return -EINVAL;
}

/* Delete the options we've used; any not deleted will cause the
* block layer to give an error about unused options.
*/
qdict_del(options, "host");
qdict_del(options, "port");
qdict_del(options, "user");
qdict_del(options, "path");
qdict_del(options, "host_key_check");

return 0;

err:
Expand All @@ -646,6 +675,8 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
}
s->session = NULL;

qemu_opts_del(opts);

return ret;
}

Expand Down

0 comments on commit 8a6a808

Please sign in to comment.