Hi.
Attached is the RFC version of patch (against old version of libvirt)
which compiles out support for SSL encryption on libvirt connections.
It is meant only to provoke a discussion whether such option is deemed
acceptable to libvirt, or it would be a complete waste of time to rebase
this patch to current git and improve it by disabling other SSL-related
functionality.
The motivation behind the change: making possible to configure libvirt
to rely on absolute minimum of other libraries. Resulting configuration
ought to connect to local libvirt daemon through Unix sockets.
--
Mikhail Gusarov
Software Engineer
CFEngine AS
Nydalsveien 33
0484 Oslo
>From 9f0ba4f3402023a44f716a0dc032c6bf55412b59 Mon Sep 17 00:00:00 2001
From: Mikhail Gusarov <mikhail.gusarov@xxxxxxxxxxxx>
Date: Thu, 21 Jul 2011 10:03:03 +0200
Subject: [PATCH 1/2] Disable GnuTLS in remote driver
---
configure.ac | 29 +++++++++++++++++----
src/libvirt.c | 6 ++++
src/remote/remote_driver.c | 57 +++++++++++++++++++++++++++++++++++++-------
3 files changed, 77 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index ecaf9cb..0dbe38b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -672,30 +672,47 @@ CFLAGS="$old_cflags"
LIBS="$old_libs"
dnl GnuTLS library
+AC_ARG_WITH([gnutls],
+ AC_HELP_STRING([--with-gnutls], [use GnuTLS for SSL-secured communication @<:@default=check@:>@]),
+ [],
+ [with_gnutls=check])
+
GNUTLS_CFLAGS=
GNUTLS_LIBS=
GNUTLS_FOUND=no
-if test -x "$PKG_CONFIG" ; then
+if test "x$with_gnutls" = "xyes" || test "x$with_gnutls" = "xcheck"; then
+ if test -x "$PKG_CONFIG" ; then
PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_REQUIRED,
[GNUTLS_FOUND=yes], [GNUTLS_FOUND=no])
-fi
-if test "$GNUTLS_FOUND" = "no"; then
+ fi
+ if test "$GNUTLS_FOUND" = "no"; then
fail=0
old_libs="$LIBS"
AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1])
AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt])
- test $fail = 1 &&
+ if test $fail = 1; then
+ if test "x$with_gnutls" = "xcheck"; then
+ with_gnutls=no
+ else
AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt])
+ fi
+ fi
dnl Not all versions of gnutls include -lgcrypt, and so we add
dnl it explicitly for the calls to gcry_control/check_version
GNUTLS_LIBS="$LIBS -lgcrypt"
LIBS="$old_libs"
-else
+ else
GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
-fi
+ fi
+ if test "x$with_gnutls" = "xyes"; then
+ AC_DEFINE_UNQUOTED([HAVE_GNUTLS], 1,
+ [whether GnuTLS is used to SSL-secure communications])
+ fi
+fi
+AM_CONDITIONAL([HAVE_GNUTLS], [test "x$with_gnutls" = "xyes"])
AC_SUBST([GNUTLS_CFLAGS])
AC_SUBST([GNUTLS_LIBS])
diff --git a/src/libvirt.c b/src/libvirt.c
index ca383ba..928898f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -20,7 +20,9 @@
#include <assert.h>
#include <sys/wait.h>
#include <time.h>
+#if HAVE_GNUTLS
#include <gcrypt.h>
+#endif
#include <libxml/parser.h>
#include <libxml/xpath.h>
@@ -255,6 +257,7 @@ winsock_init (void)
}
#endif
+#if HAVE_GNUTLS
static int virTLSMutexInit (void **priv)
{ \
virMutexPtr lock = NULL;
@@ -307,6 +310,7 @@ static struct gcry_thread_cbs virTLSThreadImpl = {
virTLSMutexUnlock,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
+#endif
/**
@@ -331,8 +335,10 @@ virInitialize(void)
virRandomInitialize(time(NULL) ^ getpid()))
return -1;
+#if HAVE_GNUTLS
gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
gcry_check_version(NULL);
+#endif
virLogSetFromEnv();
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index a945710..f446784 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -56,9 +56,11 @@
#include <rpc/types.h>
#include <rpc/xdr.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-#include "gnutls_1_0_compat.h"
+#if HAVE_GNUTLS
+# include <gnutls/gnutls.h>
+# include <gnutls/x509.h>
+# include "gnutls_1_0_compat.h"
+#endif
#if HAVE_SASL
# include <sasl/sasl.h>
#endif
@@ -152,9 +154,11 @@ struct private_data {
int errfd; /* File handle connected to remote stderr */
int watch; /* File handle watch */
pid_t pid; /* PID of tunnel process */
+#if HAVE_GNUTLS
int uses_tls; /* TLS enabled on socket? */
- int is_secure; /* Secure if TLS or SASL or UNIX sockets */
gnutls_session_t session; /* GnuTLS session (if uses_tls != 0). */
+#endif
+ int is_secure; /* Secure if TLS or SASL or UNIX sockets */
char *type; /* Cached return from remoteType. */
int counter; /* Generates serial numbers for RPC. */
int localUses; /* Ref count for private data */
@@ -263,9 +267,11 @@ void remoteDomainEventQueueFlush(int timer, void *opaque);
/* Helper functions for remoteOpen. */
static char *get_transport_from_scheme (char *scheme);
+#if HAVE_GNUTLS
/* GnuTLS functions used by remoteOpen. */
static int initialize_gnutls(void);
static gnutls_session_t negotiate_gnutls_on_connection (virConnectPtr conn, struct private_data *priv, int no_verify);
+#endif
#ifdef WITH_LIBVIRTD
static int
@@ -373,7 +379,9 @@ doRemoteOpen (virConnectPtr conn,
int wakeupFD[2] = { -1, -1 };
char *transport_str = NULL;
enum {
+#if HAVE_GNUTLS
trans_tls,
+#endif
trans_unix,
trans_ssh,
trans_ext,
@@ -391,14 +399,19 @@ doRemoteOpen (virConnectPtr conn,
transport_str = get_transport_from_scheme (conn->uri->scheme);
if (!transport_str) {
+#if HAVE_GNUTLS
if (conn->uri->server)
transport = trans_tls;
else
+#endif
transport = trans_unix;
} else {
+#if HAVE_GNUTLS
if (STRCASEEQ (transport_str, "tls"))
transport = trans_tls;
- else if (STRCASEEQ (transport_str, "unix"))
+ else
+#endif
+ if (STRCASEEQ (transport_str, "unix"))
transport = trans_unix;
else if (STRCASEEQ (transport_str, "ssh"))
transport = trans_ssh;
@@ -409,7 +422,11 @@ doRemoteOpen (virConnectPtr conn,
else {
remoteError(VIR_ERR_INVALID_ARG, "%s",
_("remote_open: transport in URL not recognised "
- "(should be tls|unix|ssh|ext|tcp)"));
+ "(should be "
+#if HAVE_GNUTLS
+ "tls|"
+#endif
+ "unix|ssh|ext|tcp)"));
return VIR_DRV_OPEN_ERROR;
}
}
@@ -433,9 +450,11 @@ doRemoteOpen (virConnectPtr conn,
/* Remote server defaults to "localhost" if not specified. */
if (conn->uri && conn->uri->port != 0) {
if (virAsprintf(&port, "%d", conn->uri->port) == -1) goto out_of_memory;
+#if HAVE_GNUTLS
} else if (transport == trans_tls) {
port = strdup (LIBVIRTD_TLS_PORT);
if (!port) goto out_of_memory;
+#endif
} else if (transport == trans_tcp) {
port = strdup (LIBVIRTD_TCP_PORT);
if (!port) goto out_of_memory;
@@ -572,12 +591,14 @@ doRemoteOpen (virConnectPtr conn,
/* Connect to the remote service. */
switch (transport) {
+#if HAVE_GNUTLS
case trans_tls:
if (initialize_gnutls() == -1) goto failed;
priv->uses_tls = 1;
priv->is_secure = 1;
/*FALLTHROUGH*/
+#endif
case trans_tcp: {
// http://people.redhat.com/drepper/userapi-ipv6.html
struct addrinfo *res, *r;
@@ -625,6 +646,7 @@ doRemoteOpen (virConnectPtr conn,
continue;
}
+#if HAVE_GNUTLS
if (priv->uses_tls) {
priv->session =
negotiate_gnutls_on_connection
@@ -635,6 +657,7 @@ doRemoteOpen (virConnectPtr conn,
goto failed;
}
}
+#endif
goto tcp_connected;
}
@@ -959,10 +982,12 @@ doRemoteOpen (virConnectPtr conn,
close(priv->errfd);
if (priv->sock >= 0) {
+#if HAVE_GNUTLS
if (priv->uses_tls && priv->session) {
gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
gnutls_deinit (priv->session);
}
+#endif
close (priv->sock);
#ifndef WIN32
if (priv->pid > 0) {
@@ -1117,6 +1142,7 @@ get_transport_from_scheme (char *scheme)
return p ? p+1 : 0;
}
+#if HAVE_GNUTLS
/* GnuTLS functions used by remoteOpen. */
static gnutls_certificate_credentials_t x509_cred;
@@ -1139,6 +1165,7 @@ static void remote_debug_gnutls_log(int level, const char* str) {
DEBUG("%d %s", level, str);
}
+
static int
initialize_gnutls(void)
{
@@ -1413,6 +1440,7 @@ verify_certificate (virConnectPtr conn ATTRIBUTE_UNUSED,
return 0;
}
+#endif
/*----------------------------------------------------------------------*/
@@ -1434,10 +1462,12 @@ doRemoteClose (virConnectPtr conn, struct private_data *priv)
return -1;
/* Close socket. */
+#if HAVE_GNUTLS
if (priv->uses_tls && priv->session) {
gnutls_bye (priv->session, GNUTLS_SHUT_RDWR);
gnutls_deinit (priv->session);
}
+#endif
#if HAVE_SASL
if (priv->saslconn)
sasl_dispose (&priv->saslconn);
@@ -1678,8 +1708,10 @@ static int remoteIsEncrypted(virConnectPtr conn)
(xdrproc_t) xdr_remote_is_secure_ret, (char *) &ret) == -1)
goto done;
+#if HAVE_GNUTLS
if (priv->uses_tls)
encrypted = 1;
+#endif
#if HAVE_SASL
else if (priv->saslconn)
encrypted = 1;
@@ -6954,6 +6986,7 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv, int in_open,
goto cleanup;
}
+#if HAVE_GNUTLS
/* Initialize some connection props we care about */
if (priv->uses_tls) {
gnutls_cipher_algorithm_t cipher;
@@ -6975,6 +7008,7 @@ remoteAuthSASL (virConnectPtr conn, struct private_data *priv, int in_open,
goto cleanup;
}
}
+#endif
memset (&secprops, 0, sizeof secprops);
/* If we've got TLS, we don't care about SSF */
@@ -8994,7 +9028,7 @@ remoteIOWriteBuffer(struct private_data *priv,
const char *bytes, int len)
{
int ret;
-
+#if HAVE_GNUTLS
if (priv->uses_tls) {
tls_resend:
ret = gnutls_record_send (priv->session, bytes, len);
@@ -9007,7 +9041,9 @@ remoteIOWriteBuffer(struct private_data *priv,
remoteError(VIR_ERR_GNUTLS_ERROR, "%s", gnutls_strerror (ret));
return -1;
}
- } else {
+ } else
+#endif
+ {
resend:
ret = send (priv->sock, bytes, len, 0);
if (ret == -1) {
@@ -9032,6 +9068,7 @@ remoteIOReadBuffer(struct private_data *priv,
{
int ret;
+#if HAVE_GNUTLS
if (priv->uses_tls) {
tls_resend:
ret = gnutls_record_recv (priv->session, bytes, len);
@@ -9051,7 +9088,9 @@ remoteIOReadBuffer(struct private_data *priv,
_("server closed connection"));
return -1;
}
- } else {
+ } else
+#endif
+ {
resend:
ret = recv (priv->sock, bytes, len, 0);
if (ret <= 0) {
--
1.7.4.1
--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list