On 08/03/2012 08:03 AM, Peter Krempa wrote:
This patch adds helper functions to libssh2 that enable us to use
libssh2 in conjunction with libvirt-native virNetSockets instead of
using a spawned "ssh" client process.
This implemetation supports tunneled plaintext, keyboard-interactive,
s/implemtation/implementation/
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, as 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 supported.
As a bonus, this should (untested) add SSH support to libvirt clients
running on Windows.
if test "$with_phyp" = "yes"; then
AC_DEFINE_UNQUOTED([WITH_PHYP], 1, [whether IBM HMC / IVM driver is enabled])
fi
+if test "$with_libssh2_transport" = "yes"; then
+ AC_DEFINE_UNQUOTED([HAVE_LIBSSH2], 1, [wether libssh2 transport is enabled])
s/wether/whether/
+++ b/src/Makefile.am
@@ -1508,6 +1508,13 @@ libvirt_net_rpc_la_SOURCES = \
rpc/virnettlscontext.h rpc/virnettlscontext.c \
rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c \
rpc/virkeepalive.h rpc/virkeepalive.c
+if HAVE_LIBSSH2
+libvirt_net_rpc_la_SOURCES += \
+ rpc/virnetlibsshcontext.h rpc/virnetlibsshcontext.c
+else
+EXTRA_DIST += \
+ rpc/virnetlibsshcontext.h rpc/virnetlibsshcontext.c
+endif
Doing it this way requires a separate .syms file. How hard would it be
to provide stub symbols, so that we always compile and link against the
file, but the file is a no-op when HAVE_LIBSSH2 is not available?
+++ b/src/rpc/virnetlibsshcontext.c
+/* keyboard interactive authentication callback */
+static void
+virNetLibSSHKbIntCb(const char *name ATTRIBUTE_UNUSED,
+ int name_len ATTRIBUTE_UNUSED,
+ const char *instruction ATTRIBUTE_UNUSED,
+ int instruction_len ATTRIBUTE_UNUSED,
+ int num_prompts,
+ const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
+ LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
+ void **opaque)
+{
prompts is marked 'const', but...
+ /* fill data structures for auth callback */
+ for (i = 0; i < num_prompts; i++) {
+ /* remove colon and trailing spaces from prompts, as default behavior
+ * of libvirt's auth callback is to add them */
+ if ((tmp = strrchr(prompts[i].text, ':')))
+ *tmp = '\0';
...you are modifying it in-place by using strrchr to cast away const.
Is that an issue where you could cause a SEGV, and should be strdup'ing
the prompt before modifying it?
+/* check session host keys
+ *
+ * this function checks the known host database and verifies the key
+ * errors are raised in this func
+ *
+ * return value: 0 on success, not 0 otherwise
+ */
+static int
+virNetLibSSHCheckHostKey(virNetLibSSHSessionPtr sess)
Is the return always negative on error?
+ /* format the host key into a nice userfriendly string.
+ * Sadly, there's no constant to describe the hash length, so
+ * we have to use a *MAGIC* constant. */
+ for (i = 0; i < 16; i++) {
+ virBufferAsprintf(&buff, "%02X", (unsigned char)
keyhash[i]);
Is the cast there to avoid unintentional sign-extension because
keyhash[i] might be signed? If so, you could avoid the cast by telling
asprintf that you are passing 1 byte in the first place with the 'hh'
modifier.
+ if (i != 15)
+ virBufferAddChar(&buff, ':');
+ }
Slightly more efficient to use:
for (i = 0; i < 16; i++)
virBufferAsprintf(&buff, "%02hhX:", keyhash[i]);
virBufferTrim(&buff, ":", 1);
+
+ if (STRNEQ_NULLABLE(askKey.result, _("yes"))) {
+ virReportError(VIR_ERR_LIBSSH_ERROR,
+ _("SSH host key for '%s' (%s) was not
accepted"),
When parsing user input, don't you want a case-insensitive comparison?
Also, what about users that want to type 'y' instead of 'yes'? And is
comparing to a translated string wise? Without consulting LC_MESSAGES
for the proper regex for the user's chosen locale, I'd almost feel safer
with a check hard-coded to English 'y' and 'n' rather than to the
arbitrary language _("yes").
I'm not quite sure how I would test all of the code, but the bulk of it
looked sane by just glancing over it. Having not specifically coded
with libssh2, I can't say if you were using the library API correctly
without spending a lot longer on the review; but if it is possible to
easily test the results, that would go a long way to convince me that
the code itself is doing the right thing.
--
Eric Blake eblake(a)redhat.com +1-919-301-3266
Libvirt virtualization library
http://libvirt.org