The libssh2 code wasn't supposed to create the known_hosts file, but recent findings show, that we can't use the default created by OpenSSH as libssh2 might damage it. We need to create a private known_hosts file in the config path. This patch adds support for skipping error if the known_host file is not present and let libssh2 create a new one. --- src/rpc/virnetsocket.c | 4 ++-- src/rpc/virnetsshsession.c | 26 ++++++++++++++++---------- src/rpc/virnetsshsession.h | 9 +++++++-- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 530c081..5a48300 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -788,8 +788,8 @@ virNetSocketNewConnectLibSSH2(const char *host, host, portN, knownHosts, - false, - verify) != 0) + verify, + VIR_NET_SSH_HOSTKEY_FILE_CREATE) != 0) goto error; if (virNetSSHSessionSetChannelCommand(sess, command) != 0) diff --git a/src/rpc/virnetsshsession.c b/src/rpc/virnetsshsession.c index fe0197e..59013c7 100644 --- a/src/rpc/virnetsshsession.c +++ b/src/rpc/virnetsshsession.c @@ -1123,8 +1123,8 @@ virNetSSHSessionSetHostKeyVerification(virNetSSHSessionPtr sess, const char *hostname, int port, const char *hostsfile, - bool readonly, - virNetSSHHostkeyVerify opt) + virNetSSHHostkeyVerify opt, + unsigned int flags) { char *errmsg; @@ -1140,19 +1140,25 @@ virNetSSHSessionSetHostKeyVerification(virNetSSHSessionPtr sess, /* load the known hosts file */ if (hostsfile) { - if (libssh2_knownhost_readfile(sess->knownHosts, - hostsfile, - LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) { - libssh2_session_last_error(sess->session, &errmsg, NULL, 0); + if (virFileExists(hostsfile)) { + if (libssh2_knownhost_readfile(sess->knownHosts, + hostsfile, + LIBSSH2_KNOWNHOST_FILE_OPENSSH) < 0) { + libssh2_session_last_error(sess->session, &errmsg, NULL, 0); + virReportError(VIR_ERR_SSH, + _("unable to load knownhosts file '%s': %s"), + hostsfile, errmsg); + goto error; + } + } else if (!(flags & VIR_NET_SSH_HOSTKEY_FILE_CREATE)) { virReportError(VIR_ERR_SSH, - _("unable to load knownhosts file '%s': %s"), - hostsfile, errmsg); + _("known hosts file '%s' does not exist"), + hostsfile); goto error; } /* set filename only if writing to the known hosts file is requested */ - - if (!readonly) { + if (!(flags & VIR_NET_SSH_HOSTKEY_FILE_READONLY)) { VIR_FREE(sess->knownHostsFile); if (!(sess->knownHostsFile = strdup(hostsfile))) goto no_memory; diff --git a/src/rpc/virnetsshsession.h b/src/rpc/virnetsshsession.h index eb92e43..1199eef 100644 --- a/src/rpc/virnetsshsession.h +++ b/src/rpc/virnetsshsession.h @@ -36,6 +36,11 @@ typedef enum { VIR_NET_SSH_HOSTKEY_VERIFY_IGNORE } virNetSSHHostkeyVerify; +typedef enum { + VIR_NET_SSH_HOSTKEY_FILE_READONLY = 1 << 0, + VIR_NET_SSH_HOSTKEY_FILE_CREATE = 1 << 1, +} virNetSSHHostKeyFileFlags; + int virNetSSHSessionSetChannelCommand(virNetSSHSessionPtr sess, const char *command); @@ -64,8 +69,8 @@ int virNetSSHSessionSetHostKeyVerification(virNetSSHSessionPtr sess, const char *hostname, int port, const char *hostsfile, - bool readonly, - virNetSSHHostkeyVerify opt); + virNetSSHHostkeyVerify opt, + unsigned int flags); int virNetSSHSessionConnect(virNetSSHSessionPtr sess, int sock); -- 1.7.8.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list