mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-03 15:43:51 +00:00
libssh2_transport: add main libssh2 transport implementation
This patch adds helper functions that enable us to use libssh2 in conjunction with libvirt's virNetSockets for ssh transport instead of spawning "ssh" client process. This implemetation supports tunneled plaintext, keyboard-interactive, private key, ssh agent based and null authentication. Libvirt's Auth callback is used for interaction with the user. (Keyboard interactive authentication, adding of host keys, private key passphrases). This enables seamless integration into the application using libvirt. No helpers as "ssh-askpass" are needed. Reading and writing of OpenSSH style "known_hosts" files is supported. Communication is done using SSH exec channel, where the user may specify arbitrary command to be executed on the remote side and reads and writes to/from stdin/out are sent through the ssh channel. Usage of stderr is not (yet) supported.
This commit is contained in:
parent
9136032a66
commit
1193fc5f44
38
configure.ac
38
configure.ac
@ -112,6 +112,7 @@ OPENWSMAN_REQUIRED="2.2.3"
|
|||||||
LIBPCAP_REQUIRED="1.0.0"
|
LIBPCAP_REQUIRED="1.0.0"
|
||||||
LIBNL_REQUIRED="1.1"
|
LIBNL_REQUIRED="1.1"
|
||||||
LIBSSH2_REQUIRED="1.0"
|
LIBSSH2_REQUIRED="1.0"
|
||||||
|
LIBSSH2_TRANSPORT_REQUIRED="1.3"
|
||||||
LIBBLKID_REQUIRED="2.17"
|
LIBBLKID_REQUIRED="2.17"
|
||||||
DBUS_REQUIRED="1.0.0"
|
DBUS_REQUIRED="1.0.0"
|
||||||
|
|
||||||
@ -440,6 +441,8 @@ AC_ARG_WITH([console-lock-files],
|
|||||||
(use auto for default paths on some platforms)
|
(use auto for default paths on some platforms)
|
||||||
@<:@default=auto@:>@]),
|
@<:@default=auto@:>@]),
|
||||||
[],[with_console_lock_files=auto])
|
[],[with_console_lock_files=auto])
|
||||||
|
AC_ARG_WITH([libssh2_transport],
|
||||||
|
AC_HELP_STRING([--with-libssh2_transport], [libssh2 location @<:@default=check@:>@]),[],[with_libssh2_transport=check])
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl in case someone want to build static binaries
|
dnl in case someone want to build static binaries
|
||||||
@ -1748,29 +1751,58 @@ AM_CONDITIONAL([WITH_UML], [test "$with_uml" = "yes"])
|
|||||||
|
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl check for libssh2 (PHYP)
|
dnl check for libssh2 (PHYP and libssh2 transport)
|
||||||
dnl
|
dnl
|
||||||
|
|
||||||
LIBSSH2_CFLAGS=""
|
LIBSSH2_CFLAGS=""
|
||||||
LIBSSH2_LIBS=""
|
LIBSSH2_LIBS=""
|
||||||
|
|
||||||
if test "$with_phyp" = "yes" || test "$with_phyp" = "check"; then
|
if test "$with_phyp" = "yes" || test "$with_phyp" = "check" ||
|
||||||
|
test "$with_libssh2_transport" = "yes" || test "$with_libssh2_transport" = "check"; then
|
||||||
PKG_CHECK_MODULES([LIBSSH2], [libssh2 >= $LIBSSH2_REQUIRED], [
|
PKG_CHECK_MODULES([LIBSSH2], [libssh2 >= $LIBSSH2_REQUIRED], [
|
||||||
|
if test "$with_phyp" = "check"; then
|
||||||
with_phyp=yes
|
with_phyp=yes
|
||||||
|
fi
|
||||||
|
if $PKG_CONFIG "libssh2 >= $LIBSSH2_TRANSPORT_REQUIRED"; then
|
||||||
|
if test "$with_libssh2_transport" = "check"; then
|
||||||
|
with_libssh2_transport=yes
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if test "$with_libssh2_transport" = "check"; then
|
||||||
|
with_libssh2_transport=no
|
||||||
|
AC_MSG_NOTICE([libssh2 >= $LIBSSH2_TRANSPORT_REQUIRED is required for libssh2 transport])
|
||||||
|
fi
|
||||||
|
if test "$with_libssh2_transport" = "yes"; then
|
||||||
|
AC_MSG_ERROR([libssh2 >= $LIBSSH2_TRANSPORT_REQUIRED is required for libssh2 transport])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
], [
|
], [
|
||||||
if test "$with_phyp" = "check"; then
|
if test "$with_phyp" = "check"; then
|
||||||
with_phyp=no
|
with_phyp=no
|
||||||
AC_MSG_NOTICE([libssh2 is required for Phyp driver, disabling it])
|
AC_MSG_NOTICE([libssh2 is required for Phyp driver, disabling it])
|
||||||
else
|
fi
|
||||||
|
if test "$with_phyp" = "yes"; then
|
||||||
AC_MSG_ERROR([libssh2 >= $LIBSSH2_REQUIRED is required for Phyp driver])
|
AC_MSG_ERROR([libssh2 >= $LIBSSH2_REQUIRED is required for Phyp driver])
|
||||||
fi
|
fi
|
||||||
|
if test "$with_libssh2_transport" = "check"; then
|
||||||
|
with_libssh2_transport=no
|
||||||
|
AC_MSG_NOTICE([libssh2 >= $LIBSSH2_TRANSPORT_REQUIRED is required for libssh2 transport])
|
||||||
|
fi
|
||||||
|
if test "$with_libssh2_transport" = "yes"; then
|
||||||
|
AC_MSG_ERROR([libssh2 >= $LIBSSH2_TRANSPORT_REQUIRED is required for libssh2 transport])
|
||||||
|
fi
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$with_phyp" = "yes"; then
|
if test "$with_phyp" = "yes"; then
|
||||||
AC_DEFINE_UNQUOTED([WITH_PHYP], 1, [whether IBM HMC / IVM driver is enabled])
|
AC_DEFINE_UNQUOTED([WITH_PHYP], 1, [whether IBM HMC / IVM driver is enabled])
|
||||||
fi
|
fi
|
||||||
|
if test "$with_libssh2_transport" = "yes"; then
|
||||||
|
AC_DEFINE_UNQUOTED([HAVE_LIBSSH2], 1, [whether libssh2 transport is enabled])
|
||||||
|
fi
|
||||||
|
|
||||||
AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"])
|
AM_CONDITIONAL([WITH_PHYP],[test "$with_phyp" = "yes"])
|
||||||
|
AM_CONDITIONAL([HAVE_LIBSSH2], [test "$with_libssh2_transport" = "yes"])
|
||||||
|
|
||||||
AC_SUBST([LIBSSH2_CFLAGS])
|
AC_SUBST([LIBSSH2_CFLAGS])
|
||||||
AC_SUBST([LIBSSH2_LIBS])
|
AC_SUBST([LIBSSH2_LIBS])
|
||||||
|
@ -112,6 +112,8 @@ typedef enum {
|
|||||||
VIR_FROM_PARALLELS = 48, /* Error from Parallels */
|
VIR_FROM_PARALLELS = 48, /* Error from Parallels */
|
||||||
VIR_FROM_DEVICE = 49, /* Error from Device */
|
VIR_FROM_DEVICE = 49, /* Error from Device */
|
||||||
|
|
||||||
|
VIR_FROM_SSH = 50, /* Error from libssh2 connection transport */
|
||||||
|
|
||||||
# ifdef VIR_ENUM_SENTINELS
|
# ifdef VIR_ENUM_SENTINELS
|
||||||
VIR_ERR_DOMAIN_LAST
|
VIR_ERR_DOMAIN_LAST
|
||||||
# endif
|
# endif
|
||||||
@ -280,6 +282,7 @@ typedef enum {
|
|||||||
VIR_ERR_BLOCK_COPY_ACTIVE = 83, /* action prevented by block copy job */
|
VIR_ERR_BLOCK_COPY_ACTIVE = 83, /* action prevented by block copy job */
|
||||||
VIR_ERR_OPERATION_UNSUPPORTED = 84, /* The requested operation is not
|
VIR_ERR_OPERATION_UNSUPPORTED = 84, /* The requested operation is not
|
||||||
supported */
|
supported */
|
||||||
|
VIR_ERR_SSH = 85, /* error in ssh transport driver */
|
||||||
} virErrorNumber;
|
} virErrorNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -100,6 +100,7 @@ src/rpc/virnetserver.c
|
|||||||
src/rpc/virnetserverclient.c
|
src/rpc/virnetserverclient.c
|
||||||
src/rpc/virnetservermdns.c
|
src/rpc/virnetservermdns.c
|
||||||
src/rpc/virnetserverprogram.c
|
src/rpc/virnetserverprogram.c
|
||||||
|
src/rpc/virnetsshsession.c
|
||||||
src/rpc/virnettlscontext.c
|
src/rpc/virnettlscontext.c
|
||||||
src/secret/secret_driver.c
|
src/secret/secret_driver.c
|
||||||
src/security/security_apparmor.c
|
src/security/security_apparmor.c
|
||||||
|
@ -1323,6 +1323,10 @@ if HAVE_SASL
|
|||||||
USED_SYM_FILES += libvirt_sasl.syms
|
USED_SYM_FILES += libvirt_sasl.syms
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if HAVE_LIBSSH2
|
||||||
|
USED_SYM_FILES += libvirt_libssh2.syms
|
||||||
|
endif
|
||||||
|
|
||||||
if WITH_ATOMIC_OPS_PTHREAD
|
if WITH_ATOMIC_OPS_PTHREAD
|
||||||
USED_SYM_FILES += libvirt_atomic.syms
|
USED_SYM_FILES += libvirt_atomic.syms
|
||||||
endif
|
endif
|
||||||
@ -1339,7 +1343,8 @@ EXTRA_DIST += \
|
|||||||
libvirt_qemu.syms \
|
libvirt_qemu.syms \
|
||||||
libvirt_sasl.syms \
|
libvirt_sasl.syms \
|
||||||
libvirt_vmx.syms \
|
libvirt_vmx.syms \
|
||||||
libvirt_xenxs.syms
|
libvirt_xenxs.syms \
|
||||||
|
libvirt_libssh2.syms
|
||||||
|
|
||||||
GENERATED_SYM_FILES = libvirt.syms libvirt.def libvirt_qemu.def
|
GENERATED_SYM_FILES = libvirt.syms libvirt.def libvirt_qemu.def
|
||||||
|
|
||||||
@ -1518,6 +1523,13 @@ libvirt_net_rpc_la_SOURCES = \
|
|||||||
rpc/virnettlscontext.h rpc/virnettlscontext.c \
|
rpc/virnettlscontext.h rpc/virnettlscontext.c \
|
||||||
rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c \
|
rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c \
|
||||||
rpc/virkeepalive.h rpc/virkeepalive.c
|
rpc/virkeepalive.h rpc/virkeepalive.c
|
||||||
|
if HAVE_LIBSSH2
|
||||||
|
libvirt_net_rpc_la_SOURCES += \
|
||||||
|
rpc/virnetsshsession.h rpc/virnetsshsession.c
|
||||||
|
else
|
||||||
|
EXTRA_DIST += \
|
||||||
|
rpc/virnetsshsession.h rpc/virnetsshsession.c
|
||||||
|
endif
|
||||||
if HAVE_SASL
|
if HAVE_SASL
|
||||||
libvirt_net_rpc_la_SOURCES += \
|
libvirt_net_rpc_la_SOURCES += \
|
||||||
rpc/virnetsaslcontext.h rpc/virnetsaslcontext.c
|
rpc/virnetsaslcontext.h rpc/virnetsaslcontext.c
|
||||||
@ -1528,11 +1540,13 @@ endif
|
|||||||
libvirt_net_rpc_la_CFLAGS = \
|
libvirt_net_rpc_la_CFLAGS = \
|
||||||
$(GNUTLS_CFLAGS) \
|
$(GNUTLS_CFLAGS) \
|
||||||
$(SASL_CFLAGS) \
|
$(SASL_CFLAGS) \
|
||||||
|
$(LIBSSH2_CFLAGS) \
|
||||||
$(XDR_CFLAGS) \
|
$(XDR_CFLAGS) \
|
||||||
$(AM_CFLAGS)
|
$(AM_CFLAGS)
|
||||||
libvirt_net_rpc_la_LDFLAGS = \
|
libvirt_net_rpc_la_LDFLAGS = \
|
||||||
$(GNUTLS_LIBS) \
|
$(GNUTLS_LIBS) \
|
||||||
$(SASL_LIBS) \
|
$(SASL_LIBS) \
|
||||||
|
$(LIBSSH2_LIBS)\
|
||||||
$(AM_LDFLAGS) \
|
$(AM_LDFLAGS) \
|
||||||
$(CYGWIN_EXTRA_LDFLAGS) \
|
$(CYGWIN_EXTRA_LDFLAGS) \
|
||||||
$(MINGW_EXTRA_LDFLAGS)
|
$(MINGW_EXTRA_LDFLAGS)
|
||||||
|
18
src/libvirt_libssh2.syms
Normal file
18
src/libvirt_libssh2.syms
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#
|
||||||
|
# ssh session - specific symbols
|
||||||
|
#
|
||||||
|
|
||||||
|
# virnetsshsession.h
|
||||||
|
#
|
||||||
|
virNetSSHChannelRead;
|
||||||
|
virNetSSHChannelWrite;
|
||||||
|
virNetSSHSessionAuthAddAgentAuth;
|
||||||
|
virNetSSHSessionAuthAddKeyboardAuth;
|
||||||
|
virNetSSHSessionAuthAddPasswordAuth;
|
||||||
|
virNetSSHSessionAuthAddPrivKeyAuth;
|
||||||
|
virNetSSHSessionAuthReset;
|
||||||
|
virNetSSHSessionAuthSetCallback;
|
||||||
|
virNetSSHSessionConnect;
|
||||||
|
virNetSSHSessionHasCachedData;
|
||||||
|
virNetSSHSessionSetChannelCommand;
|
||||||
|
virNetSSHSessionSetHostKeyVerification;
|
1472
src/rpc/virnetsshsession.c
Normal file
1472
src/rpc/virnetsshsession.c
Normal file
File diff suppressed because it is too large
Load Diff
83
src/rpc/virnetsshsession.h
Normal file
83
src/rpc/virnetsshsession.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* virnetsshsession.h: ssh transport provider based on libssh2
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Author: Peter Krempa <pkrempa@redhat.com>
|
||||||
|
*/
|
||||||
|
#ifndef __VIR_NET_SSH_SESSION_H__
|
||||||
|
# define __VIR_NET_SSH_SESSION_H__
|
||||||
|
|
||||||
|
# include "internal.h"
|
||||||
|
|
||||||
|
typedef struct _virNetSSHSession virNetSSHSession;
|
||||||
|
typedef virNetSSHSession *virNetSSHSessionPtr;
|
||||||
|
|
||||||
|
virNetSSHSessionPtr virNetSSHSessionNew(void);
|
||||||
|
void virNetSSHSessionFree(virNetSSHSessionPtr sess);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
VIR_NET_SSH_HOSTKEY_VERIFY_NORMAL,
|
||||||
|
VIR_NET_SSH_HOSTKEY_VERIFY_AUTO_ADD,
|
||||||
|
VIR_NET_SSH_HOSTKEY_VERIFY_IGNORE
|
||||||
|
} virNetSSHHostkeyVerify;
|
||||||
|
|
||||||
|
int virNetSSHSessionSetChannelCommand(virNetSSHSessionPtr sess,
|
||||||
|
const char *command);
|
||||||
|
|
||||||
|
void virNetSSHSessionAuthReset(virNetSSHSessionPtr sess);
|
||||||
|
|
||||||
|
int virNetSSHSessionAuthSetCallback(virNetSSHSessionPtr sess,
|
||||||
|
virConnectAuthPtr auth);
|
||||||
|
|
||||||
|
int virNetSSHSessionAuthAddPasswordAuth(virNetSSHSessionPtr sess,
|
||||||
|
const char *username,
|
||||||
|
const char *password);
|
||||||
|
|
||||||
|
int virNetSSHSessionAuthAddAgentAuth(virNetSSHSessionPtr sess,
|
||||||
|
const char *username);
|
||||||
|
|
||||||
|
int virNetSSHSessionAuthAddPrivKeyAuth(virNetSSHSessionPtr sess,
|
||||||
|
const char *username,
|
||||||
|
const char *keyfile,
|
||||||
|
const char *password);
|
||||||
|
|
||||||
|
int virNetSSHSessionAuthAddKeyboardAuth(virNetSSHSessionPtr sess,
|
||||||
|
const char *username,
|
||||||
|
int tries);
|
||||||
|
|
||||||
|
int virNetSSHSessionSetHostKeyVerification(virNetSSHSessionPtr sess,
|
||||||
|
const char *hostname,
|
||||||
|
int port,
|
||||||
|
const char *hostsfile,
|
||||||
|
bool readonly,
|
||||||
|
virNetSSHHostkeyVerify opt);
|
||||||
|
|
||||||
|
int virNetSSHSessionConnect(virNetSSHSessionPtr sess,
|
||||||
|
int sock);
|
||||||
|
|
||||||
|
ssize_t virNetSSHChannelRead(virNetSSHSessionPtr sess,
|
||||||
|
char *buf,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
|
ssize_t virNetSSHChannelWrite(virNetSSHSessionPtr sess,
|
||||||
|
const char *buf,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
|
bool virNetSSHSessionHasCachedData(virNetSSHSessionPtr sess);
|
||||||
|
|
||||||
|
#endif /* ___VIR_NET_SSH_SESSION_H_ */
|
@ -113,7 +113,9 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST,
|
|||||||
"Authentication Utils",
|
"Authentication Utils",
|
||||||
"DBus Utils",
|
"DBus Utils",
|
||||||
"Parallels Cloud Server",
|
"Parallels Cloud Server",
|
||||||
"Device Config"
|
"Device Config",
|
||||||
|
|
||||||
|
"SSH transport layer" /* 50 */
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -1192,6 +1194,11 @@ virErrorMsg(virErrorNumber error, const char *info)
|
|||||||
else
|
else
|
||||||
errmsg = _("Operation not supported: %s");
|
errmsg = _("Operation not supported: %s");
|
||||||
break;
|
break;
|
||||||
|
case VIR_ERR_SSH:
|
||||||
|
if (info == NULL)
|
||||||
|
errmsg = _("SSH transport error");
|
||||||
|
else
|
||||||
|
errmsg = _("SSH transport error: %s");
|
||||||
}
|
}
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user