|
|
05bba0 |
From 6151164b6f33870c511a7f5f0f64356bb8fe2ff2 Mon Sep 17 00:00:00 2001
|
|
|
05bba0 |
From: Richard Jones <rjones@redhat.com>
|
|
|
05bba0 |
Date: Mon, 8 Jun 2015 11:56:56 +0200
|
|
|
05bba0 |
Subject: [PATCH 03/30] block/ssh: Propagate errors through check_host_key()
|
|
|
05bba0 |
|
|
|
05bba0 |
Message-id: <1433764620-20506-3-git-send-email-rjones@redhat.com>
|
|
|
05bba0 |
Patchwork-id: 65479
|
|
|
05bba0 |
O-Subject: [RHEL-7.2 qemu-kvm PATCH 2/6] block/ssh: Propagate errors through check_host_key()
|
|
|
05bba0 |
Bugzilla: 1226683
|
|
|
05bba0 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
05bba0 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
From: Markus Armbruster <armbru@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
|
|
05bba0 |
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
|
|
|
05bba0 |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
05bba0 |
|
|
|
05bba0 |
Upstream-status: 01c2b265fce921d6460e06f5af4dfb405119cbab
|
|
|
05bba0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
05bba0 |
---
|
|
|
05bba0 |
block/ssh.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-----------------
|
|
|
05bba0 |
1 file changed, 49 insertions(+), 19 deletions(-)
|
|
|
05bba0 |
|
|
|
05bba0 |
diff --git a/block/ssh.c b/block/ssh.c
|
|
|
05bba0 |
index 1f7c6ed..6ffcff1 100644
|
|
|
05bba0 |
--- a/block/ssh.c
|
|
|
05bba0 |
+++ b/block/ssh.c
|
|
|
05bba0 |
@@ -106,6 +106,31 @@ static void ssh_state_free(BDRVSSHState *s)
|
|
|
05bba0 |
}
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
+static void GCC_FMT_ATTR(3, 4)
|
|
|
05bba0 |
+session_error_setg(Error **errp, BDRVSSHState *s, const char *fs, ...)
|
|
|
05bba0 |
+{
|
|
|
05bba0 |
+ va_list args;
|
|
|
05bba0 |
+ char *msg;
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ va_start(args, fs);
|
|
|
05bba0 |
+ msg = g_strdup_vprintf(fs, args);
|
|
|
05bba0 |
+ va_end(args);
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ if (s->session) {
|
|
|
05bba0 |
+ char *ssh_err;
|
|
|
05bba0 |
+ int ssh_err_code;
|
|
|
05bba0 |
+
|
|
|
05bba0 |
+ /* This is not an errno. See <libssh2.h>. */
|
|
|
05bba0 |
+ ssh_err_code = libssh2_session_last_error(s->session,
|
|
|
05bba0 |
+ &ssh_err, NULL, 0);
|
|
|
05bba0 |
+ error_setg(errp, "%s: %s (libssh2 error code: %d)",
|
|
|
05bba0 |
+ msg, ssh_err, ssh_err_code);
|
|
|
05bba0 |
+ } else {
|
|
|
05bba0 |
+ error_setg(errp, "%s", msg);
|
|
|
05bba0 |
+ }
|
|
|
05bba0 |
+ g_free(msg);
|
|
|
05bba0 |
+}
|
|
|
05bba0 |
+
|
|
|
05bba0 |
/* Wrappers around error_report which make sure to dump as much
|
|
|
05bba0 |
* information from libssh2 as possible.
|
|
|
05bba0 |
*/
|
|
|
05bba0 |
@@ -242,7 +267,7 @@ static void ssh_parse_filename(const char *filename, QDict *options,
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
static int check_host_key_knownhosts(BDRVSSHState *s,
|
|
|
05bba0 |
- const char *host, int port)
|
|
|
05bba0 |
+ const char *host, int port, Error **errp)
|
|
|
05bba0 |
{
|
|
|
05bba0 |
const char *home;
|
|
|
05bba0 |
char *knh_file = NULL;
|
|
|
05bba0 |
@@ -256,14 +281,15 @@ static int check_host_key_knownhosts(BDRVSSHState *s,
|
|
|
05bba0 |
hostkey = libssh2_session_hostkey(s->session, &len, &type);
|
|
|
05bba0 |
if (!hostkey) {
|
|
|
05bba0 |
ret = -EINVAL;
|
|
|
05bba0 |
- session_error_report(s, "failed to read remote host key");
|
|
|
05bba0 |
+ session_error_setg(errp, s, "failed to read remote host key");
|
|
|
05bba0 |
goto out;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
knh = libssh2_knownhost_init(s->session);
|
|
|
05bba0 |
if (!knh) {
|
|
|
05bba0 |
ret = -EINVAL;
|
|
|
05bba0 |
- session_error_report(s, "failed to initialize known hosts support");
|
|
|
05bba0 |
+ session_error_setg(errp, s,
|
|
|
05bba0 |
+ "failed to initialize known hosts support");
|
|
|
05bba0 |
goto out;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
@@ -288,21 +314,23 @@ static int check_host_key_knownhosts(BDRVSSHState *s,
|
|
|
05bba0 |
break;
|
|
|
05bba0 |
case LIBSSH2_KNOWNHOST_CHECK_MISMATCH:
|
|
|
05bba0 |
ret = -EINVAL;
|
|
|
05bba0 |
- session_error_report(s, "host key does not match the one in known_hosts (found key %s)",
|
|
|
05bba0 |
- found->key);
|
|
|
05bba0 |
+ session_error_setg(errp, s,
|
|
|
05bba0 |
+ "host key does not match the one in known_hosts"
|
|
|
05bba0 |
+ " (found key %s)", found->key);
|
|
|
05bba0 |
goto out;
|
|
|
05bba0 |
case LIBSSH2_KNOWNHOST_CHECK_NOTFOUND:
|
|
|
05bba0 |
ret = -EINVAL;
|
|
|
05bba0 |
- session_error_report(s, "no host key was found in known_hosts");
|
|
|
05bba0 |
+ session_error_setg(errp, s, "no host key was found in known_hosts");
|
|
|
05bba0 |
goto out;
|
|
|
05bba0 |
case LIBSSH2_KNOWNHOST_CHECK_FAILURE:
|
|
|
05bba0 |
ret = -EINVAL;
|
|
|
05bba0 |
- session_error_report(s, "failure matching the host key with known_hosts");
|
|
|
05bba0 |
+ session_error_setg(errp, s,
|
|
|
05bba0 |
+ "failure matching the host key with known_hosts");
|
|
|
05bba0 |
goto out;
|
|
|
05bba0 |
default:
|
|
|
05bba0 |
ret = -EINVAL;
|
|
|
05bba0 |
- session_error_report(s, "unknown error matching the host key with known_hosts (%d)",
|
|
|
05bba0 |
- r);
|
|
|
05bba0 |
+ session_error_setg(errp, s, "unknown error matching the host key"
|
|
|
05bba0 |
+ " with known_hosts (%d)", r);
|
|
|
05bba0 |
goto out;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
@@ -357,20 +385,20 @@ static int compare_fingerprint(const unsigned char *fingerprint, size_t len,
|
|
|
05bba0 |
|
|
|
05bba0 |
static int
|
|
|
05bba0 |
check_host_key_hash(BDRVSSHState *s, const char *hash,
|
|
|
05bba0 |
- int hash_type, size_t fingerprint_len)
|
|
|
05bba0 |
+ int hash_type, size_t fingerprint_len, Error **errp)
|
|
|
05bba0 |
{
|
|
|
05bba0 |
const char *fingerprint;
|
|
|
05bba0 |
|
|
|
05bba0 |
fingerprint = libssh2_hostkey_hash(s->session, hash_type);
|
|
|
05bba0 |
if (!fingerprint) {
|
|
|
05bba0 |
- session_error_report(s, "failed to read remote host key");
|
|
|
05bba0 |
+ session_error_setg(errp, s, "failed to read remote host key");
|
|
|
05bba0 |
return -EINVAL;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
if(compare_fingerprint((unsigned char *) fingerprint, fingerprint_len,
|
|
|
05bba0 |
hash) != 0) {
|
|
|
05bba0 |
- error_report("remote host key does not match host_key_check '%s'",
|
|
|
05bba0 |
- hash);
|
|
|
05bba0 |
+ error_setg(errp, "remote host key does not match host_key_check '%s'",
|
|
|
05bba0 |
+ hash);
|
|
|
05bba0 |
return -EPERM;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
@@ -378,7 +406,7 @@ check_host_key_hash(BDRVSSHState *s, const char *hash,
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
static int check_host_key(BDRVSSHState *s, const char *host, int port,
|
|
|
05bba0 |
- const char *host_key_check)
|
|
|
05bba0 |
+ const char *host_key_check, Error **errp)
|
|
|
05bba0 |
{
|
|
|
05bba0 |
/* host_key_check=no */
|
|
|
05bba0 |
if (strcmp(host_key_check, "no") == 0) {
|
|
|
05bba0 |
@@ -388,21 +416,21 @@ static int check_host_key(BDRVSSHState *s, const char *host, int port,
|
|
|
05bba0 |
/* host_key_check=md5:xx:yy:zz:... */
|
|
|
05bba0 |
if (strncmp(host_key_check, "md5:", 4) == 0) {
|
|
|
05bba0 |
return check_host_key_hash(s, &host_key_check[4],
|
|
|
05bba0 |
- LIBSSH2_HOSTKEY_HASH_MD5, 16);
|
|
|
05bba0 |
+ LIBSSH2_HOSTKEY_HASH_MD5, 16, errp);
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
/* host_key_check=sha1:xx:yy:zz:... */
|
|
|
05bba0 |
if (strncmp(host_key_check, "sha1:", 5) == 0) {
|
|
|
05bba0 |
return check_host_key_hash(s, &host_key_check[5],
|
|
|
05bba0 |
- LIBSSH2_HOSTKEY_HASH_SHA1, 20);
|
|
|
05bba0 |
+ LIBSSH2_HOSTKEY_HASH_SHA1, 20, errp);
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
/* host_key_check=yes */
|
|
|
05bba0 |
if (strcmp(host_key_check, "yes") == 0) {
|
|
|
05bba0 |
- return check_host_key_knownhosts(s, host, port);
|
|
|
05bba0 |
+ return check_host_key_knownhosts(s, host, port, errp);
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
- error_report("unknown host_key_check setting (%s)", host_key_check);
|
|
|
05bba0 |
+ error_setg(errp, "unknown host_key_check setting (%s)", host_key_check);
|
|
|
05bba0 |
return -EINVAL;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
@@ -541,8 +569,10 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
/* Check the remote host's key against known_hosts. */
|
|
|
05bba0 |
- ret = check_host_key(s, host, port, host_key_check);
|
|
|
05bba0 |
+ ret = check_host_key(s, host, port, host_key_check, &err;;
|
|
|
05bba0 |
if (ret < 0) {
|
|
|
05bba0 |
+ qerror_report_err(err);
|
|
|
05bba0 |
+ error_free(err);
|
|
|
05bba0 |
goto err;
|
|
|
05bba0 |
}
|
|
|
05bba0 |
|
|
|
05bba0 |
--
|
|
|
05bba0 |
1.8.3.1
|
|
|
05bba0 |
|