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