[libvirt] [PATCH] Make TLS support conditional

From: "Daniel P. Berrange" <berrange@redhat.com> Add checks for existance of GNUTLS and automatically disable it if not found. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- configure.ac | 70 ++++++++++++++++++++++++++++++++----------- daemon/libvirtd.c | 41 ++++++++++++++++++------- daemon/remote.c | 2 ++ src/Makefile.am | 8 ++++- src/libvirt.c | 17 ++++++++--- src/locking/lock_daemon.c | 12 ++++++-- src/lxc/lxc_controller.c | 6 ++-- src/qemu/qemu_migration.c | 15 ++++++++-- src/remote/remote_driver.c | 15 ++++++++++ src/rpc/virnetclient.c | 20 ++++++++++--- src/rpc/virnetclient.h | 8 ++++- src/rpc/virnetserver.c | 6 ++++ src/rpc/virnetserver.h | 6 +++- src/rpc/virnetserverclient.c | 63 ++++++++++++++++++++++++++++++++++---- src/rpc/virnetserverclient.h | 4 +++ src/rpc/virnetserverservice.c | 31 ++++++++++++++----- src/rpc/virnetserverservice.h | 20 +++++++++---- src/rpc/virnetsocket.c | 17 ++++++++++- src/rpc/virnetsocket.h | 6 +++- tests/Makefile.am | 11 ++++++- 20 files changed, 311 insertions(+), 67 deletions(-) diff --git a/configure.ac b/configure.ac index ab08f17..bb64bf6 100644 --- a/configure.ac +++ b/configure.ac @@ -1025,30 +1025,62 @@ CFLAGS="$old_cflags" LIBS="$old_libs" dnl GnuTLS library -GNUTLS_CFLAGS= -GNUTLS_LIBS= -GNUTLS_FOUND=no -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 +AC_ARG_WITH([gnutls], + AC_HELP_STRING([--with-gnutls], [use GNUTLS for encryption @<:@default=check@:>@]), + [], + [with_gnutls=check]) + + +if test "x$with_gnutls" != "xno"; then + if test "x$with_gnutls" != "xyes" && test "x$with_gnutls" != "xcheck"; then + GNUTLS_CFLAGS="-I$with_gnutls/include" + GNUTLS_LIBS="-L$with_gnutls/lib" + fi fail=0 + old_cflags="$CFLAGS" old_libs="$LIBS" - AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1]) - AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt]) + CFLAGS="$CFLAGS $GNUTLS_CFLAGS" + LIBS="$LIBS $GNUTLS_LIBS" - test $fail = 1 && - AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt]) + GNUTLS_FOUND=no + 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 + fail=0 + AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1]) + AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt]) + + test $fail = 0 && GNUTLS_FOUND=yes + + GNUTLS_LIBS="$GNUTLS_LIBS -lgnutls" + fi + if test "$GNUTLS_FOUND" = "no"; then + if test "$with_gnutls" = "check"; then + with_gnutls=no + GNUTLS_LIBS= + GNUTLS_CFLAGS= + else + AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt]) + fi + else + 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="$GNUTLS_LIBS -lgcrypt" + + with_gnutls=yes + 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 - GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt" + CFLAGS="$old_CFLAGS" fi +if test "x$with_gnutls" = "xyes" ; then + AC_DEFINE_UNQUOTED([HAVE_GNUTLS], 1, + [whether GNUTLS is available for encryption]) +fi +AM_CONDITIONAL([HAVE_GNUTLS], [test "x$with_gnutls" = "xyes"]) AC_SUBST([GNUTLS_CFLAGS]) AC_SUBST([GNUTLS_LIBS]) @@ -3168,7 +3200,11 @@ AC_MSG_NOTICE([ libssh2: $LIBSSH2_CFLAGS $LIBSSH2_LIBS]) else AC_MSG_NOTICE([ libssh2: no]) fi +if test "$with_gnutls" != "no" ; then AC_MSG_NOTICE([ gnutls: $GNUTLS_CFLAGS $GNUTLS_LIBS]) +else +AC_MSG_NOTICE([ gnutls: no]) +fi if test "$with_sasl" != "no" ; then AC_MSG_NOTICE([ sasl: $SASL_CFLAGS $SASL_LIBS]) else diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index fa4d129..ff54af3 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -449,7 +449,9 @@ static int daemonSetupNetworking(virNetServerPtr srv, virNetServerServicePtr svc = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; +#if HAVE_GNUTLS virNetServerServicePtr svcTLS = NULL; +#endif gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; @@ -474,9 +476,11 @@ static int daemonSetupNetworking(virNetServerPtr srv, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, +#if HAVE_GNUTLS + NULL, +#endif false, - config->max_client_requests, - NULL))) + config->max_client_requests))) goto error; if (sock_path_ro) { VIR_DEBUG("Registering unix socket %s", sock_path_ro); @@ -484,9 +488,11 @@ static int daemonSetupNetworking(virNetServerPtr srv, unix_sock_ro_mask, unix_sock_gid, config->auth_unix_ro, +#if HAVE_GNUTLS + NULL, +#endif true, - config->max_client_requests, - NULL))) + config->max_client_requests))) goto error; } @@ -507,9 +513,11 @@ static int daemonSetupNetworking(virNetServerPtr srv, if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr, config->tcp_port, config->auth_tcp, +#if HAVE_GNUTLS + NULL, +#endif false, - config->max_client_requests, - NULL))) + config->max_client_requests))) goto error; if (virNetServerAddService(srv, svcTCP, @@ -517,6 +525,7 @@ static int daemonSetupNetworking(virNetServerPtr srv, goto error; } +#if HAVE_GNUTLS if (config->listen_tls) { virNetTLSContextPtr ctxt = NULL; @@ -546,9 +555,9 @@ static int daemonSetupNetworking(virNetServerPtr srv, virNetServerServiceNewTCP(config->listen_addr, config->tls_port, config->auth_tls, + ctxt, false, - config->max_client_requests, - ctxt))) { + config->max_client_requests))) { virObjectUnref(ctxt); goto error; } @@ -559,13 +568,23 @@ static int daemonSetupNetworking(virNetServerPtr srv, virObjectUnref(ctxt); } +#else + (void)privileged; + if (config->listen_tls) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This libvirtd build does not support TLS")); + goto error; + } +#endif } #if HAVE_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || - config->auth_tcp == REMOTE_AUTH_SASL || - config->auth_tls == REMOTE_AUTH_SASL) { +# if HAVE_GNUTLS + config->auth_tls == REMOTE_AUTH_SASL || +# endif + config->auth_tcp == REMOTE_AUTH_SASL) { saslCtxt = virNetSASLContextNewServer( (const char *const*)config->sasl_allowed_username_list); if (!saslCtxt) @@ -576,7 +595,9 @@ static int daemonSetupNetworking(virNetServerPtr srv, return 0; error: +#if HAVE_GNUTLS virObjectUnref(svcTLS); +#endif virObjectUnref(svcTCP); virObjectUnref(svc); virObjectUnref(svcRO); diff --git a/daemon/remote.c b/daemon/remote.c index 8767c18..67fe335 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -2464,6 +2464,7 @@ remoteDispatchAuthSaslInit(virNetServerPtr server ATTRIBUTE_UNUSED, if (!sasl) goto authfail; +# if HAVE_GNUTLS /* Inform SASL that we've got an external SSF layer from TLS */ if (virNetServerClientHasTLSSession(client)) { int ssf; @@ -2477,6 +2478,7 @@ remoteDispatchAuthSaslInit(virNetServerPtr server ATTRIBUTE_UNUSED, if (virNetSASLSessionExtKeySize(sasl, ssf) < 0) goto authfail; } +# endif if (virNetServerClientIsSecure(client)) /* If we've got TLS or UNIX domain sock, we don't care about SSF */ diff --git a/src/Makefile.am b/src/Makefile.am index 955973e..061d544 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1777,7 +1777,6 @@ libvirt_net_rpc_la_SOURCES = \ rpc/virnetmessage.h rpc/virnetmessage.c \ rpc/virnetprotocol.h rpc/virnetprotocol.c \ rpc/virnetsocket.h rpc/virnetsocket.c \ - rpc/virnettlscontext.h rpc/virnettlscontext.c \ rpc/virkeepaliveprotocol.h rpc/virkeepaliveprotocol.c \ rpc/virkeepalive.h rpc/virkeepalive.c if HAVE_LIBSSH2 @@ -1787,6 +1786,13 @@ else EXTRA_DIST += \ rpc/virnetsshsession.h rpc/virnetsshsession.c endif +if HAVE_GNUTLS +libvirt_net_rpc_la_SOURCES += \ + rpc/virnettlscontext.h rpc/virnettlscontext.c +else +EXTRA_DIST += \ + rpc/virnettlscontext.h rpc/virnettlscontext.c +endif if HAVE_SASL libvirt_net_rpc_la_SOURCES += \ rpc/virnetsaslcontext.h rpc/virnetsaslcontext.c diff --git a/src/libvirt.c b/src/libvirt.c index 6d1da12..e0f6185 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -55,7 +55,9 @@ #include "configmake.h" #include "intprops.h" #include "virconf.h" -#include "rpc/virnettlscontext.h" +#if HAVE_GNUTLS +# include "rpc/virnettlscontext.h" +#endif #include "vircommand.h" #include "virrandom.h" #include "viruri.h" @@ -268,6 +270,8 @@ winsock_init(void) } #endif + +#ifdef HAVE_GNUTLS static int virTLSMutexInit(void **priv) { virMutexPtr lock = NULL; @@ -308,11 +312,11 @@ static int virTLSMutexUnlock(void **priv) static struct gcry_thread_cbs virTLSThreadImpl = { /* GCRY_THREAD_OPTION_VERSION was added in gcrypt 1.4.2 */ -#ifdef GCRY_THREAD_OPTION_VERSION +# ifdef GCRY_THREAD_OPTION_VERSION (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), -#else +# else GCRY_THREAD_OPTION_PTHREAD, -#endif +# endif NULL, virTLSMutexInit, virTLSMutexDestroy, @@ -320,6 +324,7 @@ static struct gcry_thread_cbs virTLSThreadImpl = { virTLSMutexUnlock, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +#endif /* Helper macros to implement VIR_DOMAIN_DEBUG using just C99. This * assumes you pass fewer than 15 arguments to VIR_DOMAIN_DEBUG, but @@ -403,12 +408,16 @@ virGlobalInit(void) virErrorInitialize() < 0) goto error; +#ifdef HAVE_GNUTLS gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl); gcry_check_version(NULL); +#endif virLogSetFromEnv(); +#ifdef HAVE_GNUTLS virNetTLSInit(); +#endif #if HAVE_LIBCURL curl_global_init(CURL_GLOBAL_DEFAULT); diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index 7288f7a..ba42c00 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -654,7 +654,11 @@ virLockDaemonSetupNetworkingSystemD(virNetServerPtr srv) /* Systemd passes FDs, starting immediately after stderr, * so the first FD we'll get is '3'. */ - if (!(svc = virNetServerServiceNewFD(3, 0, false, 1, NULL))) + if (!(svc = virNetServerServiceNewFD(3, 0, +#if HAVE_GNUTLS + NULL, +#endif + false, 1))) return -1; if (virNetServerAddService(srv, svc, NULL) < 0) { @@ -672,7 +676,11 @@ virLockDaemonSetupNetworkingNative(virNetServerPtr srv, const char *sock_path) VIR_DEBUG("Setting up networking natively"); - if (!(svc = virNetServerServiceNewUNIX(sock_path, 0700, 0, 0, false, 1, NULL))) + if (!(svc = virNetServerServiceNewUNIX(sock_path, 0700, 0, 0, +#if HAVE_GNUTLS + NULL, +#endif + false, 1))) return -1; if (virNetServerAddService(srv, svc, NULL) < 0) { diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index c9d96b3..ddc921e 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -631,9 +631,11 @@ static int virLXCControllerSetupServer(virLXCControllerPtr ctrl) 0700, 0, 0, +#if HAVE_GNUTLS + NULL, +#endif false, - 5, - NULL))) + 5))) goto error; if (virNetServerAddService(ctrl->server, svc, NULL) < 0) diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 9c7247b..e235677 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -23,8 +23,10 @@ #include <config.h> #include <sys/time.h> -#include <gnutls/gnutls.h> -#include <gnutls/x509.h> +#ifdef HAVE_GNUTLS +# include <gnutls/gnutls.h> +# include <gnutls/x509.h> +#endif #include <fcntl.h> #include <poll.h> @@ -196,6 +198,7 @@ static void qemuMigrationCookieFree(qemuMigrationCookiePtr mig) } +#ifdef HAVE_GNUTLS static char * qemuDomainExtractTLSSubject(const char *certdir) { @@ -254,7 +257,7 @@ error: VIR_FREE(pemdata); return NULL; } - +#endif static qemuMigrationCookieGraphicsPtr qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver, @@ -273,9 +276,11 @@ qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver, if (!listenAddr) listenAddr = driver->vncListen; +#ifdef HAVE_GNUTLS if (driver->vncTLS && !(mig->tlsSubject = qemuDomainExtractTLSSubject(driver->vncTLSx509certdir))) goto error; +#endif } else { mig->port = def->data.spice.port; if (driver->spiceTLS) @@ -286,9 +291,11 @@ qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver, if (!listenAddr) listenAddr = driver->spiceListen; +#ifdef HAVE_GNUTLS if (driver->spiceTLS && !(mig->tlsSubject = qemuDomainExtractTLSSubject(driver->spiceTLSx509certdir))) goto error; +#endif } if (!(mig->listen = strdup(listenAddr))) goto no_memory; @@ -297,7 +304,9 @@ qemuMigrationCookieGraphicsAlloc(virQEMUDriverPtr driver, no_memory: virReportOOMError(); +#ifdef HAVE_GNUTLS error: +#endif qemuMigrationCookieGraphicsFree(mig); return NULL; } diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index c078cb5..f10c68a 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -80,7 +80,9 @@ struct private_data { int counter; /* Serial number for RPC */ +#ifdef HAVE_GNUTLS virNetTLSContextPtr tls; +#endif int is_secure; /* Secure if TLS or SASL or UNIX sockets */ char *type; /* Cached return from remoteType. */ @@ -596,12 +598,19 @@ doRemoteOpen(virConnectPtr conn, /* Connect to the remote service. */ switch (transport) { case trans_tls: +#ifdef HAVE_GNUTLS priv->tls = virNetTLSContextNewClientPath(pkipath, geteuid() != 0 ? true : false, sanity, verify); if (!priv->tls) goto failed; priv->is_secure = 1; +#else + (void)sanity; + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("GNUTLS support not available in this build")); + goto failed; +#endif /*FALLTHROUGH*/ case trans_tcp: @@ -609,11 +618,13 @@ doRemoteOpen(virConnectPtr conn, if (!priv->client) goto failed; +#ifdef HAVE_GNUTLS if (priv->tls) { VIR_DEBUG("Starting TLS session"); if (virNetClientSetTLSSession(priv->client, priv->tls) < 0) goto failed; } +#endif break; @@ -1001,8 +1012,10 @@ doRemoteClose(virConnectPtr conn, struct private_data *priv) (xdrproc_t) xdr_void, (char *) NULL) == -1) ret = -1; +#ifdef HAVE_GNUTLS virObjectUnref(priv->tls); priv->tls = NULL; +#endif virNetClientSetCloseCallback(priv->client, NULL, NULL, @@ -3879,6 +3892,7 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv, saslcb))) goto cleanup; +# ifdef HAVE_GNUTLS /* Initialize some connection props we care about */ if (priv->tls) { if ((ssf = virNetClientGetTLSKeySize(priv->client)) < 0) @@ -3890,6 +3904,7 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv, if (virNetSASLSessionExtKeySize(sasl, ssf) < 0) goto cleanup; } +# endif /* If we've got a secure channel (TLS or UNIX sock), we don't care about SSF */ /* If we're not secure, then forbid any anonymous or trivially crackable auth */ diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c index 208e2e9..e933529 100644 --- a/src/rpc/virnetclient.c +++ b/src/rpc/virnetclient.c @@ -70,7 +70,9 @@ struct _virNetClient { virNetSocketPtr sock; bool asyncIO; +#if HAVE_GNUTLS virNetTLSSessionPtr tls; +#endif char *hostname; virNetClientProgramPtr *programs; @@ -627,7 +629,9 @@ void virNetClientDispose(void *obj) if (client->sock) virNetSocketRemoveIOCallback(client->sock); virObjectUnref(client->sock); +#if HAVE_GNUTLS virObjectUnref(client->tls); +#endif #if HAVE_SASL virObjectUnref(client->sasl); #endif @@ -663,8 +667,10 @@ virNetClientCloseLocked(virNetClientPtr client) virObjectUnref(client->sock); client->sock = NULL; +#if HAVE_GNUTLS virObjectUnref(client->tls); client->tls = NULL; +#endif #if HAVE_SASL virObjectUnref(client->sasl); client->sasl = NULL; @@ -745,6 +751,7 @@ void virNetClientSetSASLSession(virNetClientPtr client, #endif +#if HAVE_GNUTLS int virNetClientSetTLSSession(virNetClientPtr client, virNetTLSContextPtr tls) { @@ -755,12 +762,12 @@ int virNetClientSetTLSSession(virNetClientPtr client, sigset_t oldmask, blockedsigs; sigemptyset(&blockedsigs); -#ifdef SIGWINCH +# ifdef SIGWINCH sigaddset(&blockedsigs, SIGWINCH); -#endif -#ifdef SIGCHLD +# endif +# ifdef SIGCHLD sigaddset(&blockedsigs, SIGCHLD); -#endif +# endif sigaddset(&blockedsigs, SIGPIPE); virNetClientLock(client); @@ -847,13 +854,16 @@ error: virNetClientUnlock(client); return -1; } +#endif bool virNetClientIsEncrypted(virNetClientPtr client) { bool ret = false; virNetClientLock(client); +#if HAVE_GNUTLS if (client->tls) ret = true; +#endif #if HAVE_SASL if (client->sasl) ret = true; @@ -956,6 +966,7 @@ const char *virNetClientRemoteAddrString(virNetClientPtr client) return virNetSocketRemoteAddrString(client->sock); } +#if HAVE_GNUTLS int virNetClientGetTLSKeySize(virNetClientPtr client) { int ret = 0; @@ -965,6 +976,7 @@ int virNetClientGetTLSKeySize(virNetClientPtr client) virNetClientUnlock(client); return ret; } +#endif static int virNetClientCallDispatchReply(virNetClientPtr client) diff --git a/src/rpc/virnetclient.h b/src/rpc/virnetclient.h index 139cf32..d594add 100644 --- a/src/rpc/virnetclient.h +++ b/src/rpc/virnetclient.h @@ -23,7 +23,9 @@ #ifndef __VIR_NET_CLIENT_H__ # define __VIR_NET_CLIENT_H__ -# include "virnettlscontext.h" +# ifdef HAVE_GNUTLS +# include "virnettlscontext.h" +# endif # include "virnetmessage.h" # ifdef HAVE_SASL # include "virnetsaslcontext.h" @@ -107,8 +109,10 @@ void virNetClientSetSASLSession(virNetClientPtr client, virNetSASLSessionPtr sasl); # endif +# ifdef HAVE_GNUTLS int virNetClientSetTLSSession(virNetClientPtr client, virNetTLSContextPtr tls); +# endif bool virNetClientIsEncrypted(virNetClientPtr client); bool virNetClientIsOpen(virNetClientPtr client); @@ -116,7 +120,9 @@ bool virNetClientIsOpen(virNetClientPtr client); const char *virNetClientLocalAddrString(virNetClientPtr client); const char *virNetClientRemoteAddrString(virNetClientPtr client); +# ifdef HAVE_GNUTLS int virNetClientGetTLSKeySize(virNetClientPtr client); +# endif void virNetClientClose(virNetClientPtr client); diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c index 5674309..b9df71b 100644 --- a/src/rpc/virnetserver.c +++ b/src/rpc/virnetserver.c @@ -98,7 +98,9 @@ struct _virNetServer { unsigned int quit :1; +#ifdef HAVE_GNUTLS virNetTLSContextPtr tls; +#endif unsigned int autoShutdownTimeout; size_t autoShutdownInhibitions; @@ -309,7 +311,9 @@ static int virNetServerDispatchNewClient(virNetServerServicePtr svc, virNetServerServiceGetAuth(svc), virNetServerServiceIsReadonly(svc), virNetServerServiceGetMaxRequests(svc), +#if HAVE_GNUTLS virNetServerServiceGetTLSContext(svc), +#endif srv->clientPrivNew, srv->clientPrivPreExecRestart, srv->clientPrivFree, @@ -1034,12 +1038,14 @@ no_memory: return -1; } +#if HAVE_GNUTLS int virNetServerSetTLSContext(virNetServerPtr srv, virNetTLSContextPtr tls) { srv->tls = virObjectRef(tls); return 0; } +#endif static void virNetServerAutoShutdownTimer(int timerid ATTRIBUTE_UNUSED, diff --git a/src/rpc/virnetserver.h b/src/rpc/virnetserver.h index da7dc9e..d906dd1 100644 --- a/src/rpc/virnetserver.h +++ b/src/rpc/virnetserver.h @@ -26,7 +26,9 @@ # include <signal.h> -# include "virnettlscontext.h" +# ifdef HAVE_GNUTLS +# include "virnettlscontext.h" +# endif # include "virnetserverprogram.h" # include "virnetserverclient.h" # include "virnetserverservice.h" @@ -79,8 +81,10 @@ int virNetServerAddService(virNetServerPtr srv, int virNetServerAddProgram(virNetServerPtr srv, virNetServerProgramPtr prog); +# if HAVE_GNUTLS int virNetServerSetTLSContext(virNetServerPtr srv, virNetTLSContextPtr tls); +# endif void virNetServerUpdateServices(virNetServerPtr srv, bool enabled); diff --git a/src/rpc/virnetserverclient.c b/src/rpc/virnetserverclient.c index aefc511..bf23d24 100644 --- a/src/rpc/virnetserverclient.c +++ b/src/rpc/virnetserverclient.c @@ -66,8 +66,10 @@ struct _virNetServerClient int auth; bool readonly; char *identity; +#if HAVE_GNUTLS virNetTLSContextPtr tlsCtxt; virNetTLSSessionPtr tls; +#endif #if HAVE_SASL virNetSASLSessionPtr sasl; #endif @@ -147,13 +149,18 @@ virNetServerClientCalculateHandleMode(virNetServerClientPtr client) { VIR_DEBUG("tls=%p hs=%d, rx=%p tx=%p", +#ifdef HAVE_GNUTLS client->tls, client->tls ? virNetTLSSessionGetHandshakeStatus(client->tls) : -1, +#else + NULL, -1, +#endif client->rx, client->tx); if (!client->sock || client->wantClose) return 0; +#if HAVE_GNUTLS if (client->tls) { switch (virNetTLSSessionGetHandshakeStatus(client->tls)) { case VIR_NET_TLS_HANDSHAKE_RECVING: @@ -170,6 +177,7 @@ virNetServerClientCalculateHandleMode(virNetServerClientPtr client) { mode |= VIR_EVENT_HANDLE_WRITABLE; } } else { +#endif /* If there is a message on the rx queue, and * we're not in middle of a delayedClose, then * we're wanting more input */ @@ -180,7 +188,9 @@ virNetServerClientCalculateHandleMode(virNetServerClientPtr client) { then monitor for writability on socket */ if (client->tx) mode |= VIR_EVENT_HANDLE_WRITABLE; +#if HAVE_GNUTLS } +#endif VIR_DEBUG("mode=%o", mode); return mode; } @@ -287,6 +297,7 @@ void virNetServerClientRemoveFilter(virNetServerClientPtr client, } +#ifdef HAVE_GNUTLS /* Check the client's access. */ static int virNetServerClientCheckAccess(virNetServerClientPtr client) @@ -322,6 +333,8 @@ virNetServerClientCheckAccess(virNetServerClientPtr client) return 0; } +#endif + static void virNetServerClientSockTimerFunc(int timer, void *opaque) @@ -340,9 +353,11 @@ static void virNetServerClientSockTimerFunc(int timer, static virNetServerClientPtr virNetServerClientNewInternal(virNetSocketPtr sock, int auth, +#ifdef HAVE_GNUTLS + virNetTLSContextPtr tls, +#endif bool readonly, - size_t nrequests_max, - virNetTLSContextPtr tls) + size_t nrequests_max) { virNetServerClientPtr client; @@ -360,7 +375,9 @@ virNetServerClientNewInternal(virNetSocketPtr sock, client->sock = virObjectRef(sock); client->auth = auth; client->readonly = readonly; +#ifdef HAVE_GNUTLS client->tlsCtxt = virObjectRef(tls); +#endif client->nrequests_max = nrequests_max; client->sockTimer = virEventAddTimeout(-1, virNetServerClientSockTimerFunc, @@ -394,7 +411,9 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, int auth, bool readonly, size_t nrequests_max, +#ifdef HAVE_GNUTLS virNetTLSContextPtr tls, +#endif virNetServerClientPrivNew privNew, virNetServerClientPrivPreExecRestart privPreExecRestart, virFreeCallback privFree, @@ -402,9 +421,19 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, { virNetServerClientPtr client; - VIR_DEBUG("sock=%p auth=%d tls=%p", sock, auth, tls); + VIR_DEBUG("sock=%p auth=%d tls=%p", sock, auth, +#ifdef HAVE_GNUTLS + tls +#else + NULL +#endif + ); - if (!(client = virNetServerClientNewInternal(sock, auth, readonly, nrequests_max, tls))) + if (!(client = virNetServerClientNewInternal(sock, auth, +#ifdef HAVE_GNUTLS + tls, +#endif + readonly, nrequests_max))) return NULL; if (privNew) { @@ -470,9 +499,11 @@ virNetServerClientPtr virNetServerClientNewPostExecRestart(virJSONValuePtr objec if (!(client = virNetServerClientNewInternal(sock, auth, +#ifdef HAVE_GNUTLS + NULL, +#endif readonly, - nrequests_max, - NULL))) { + nrequests_max))) { virObjectUnref(sock); return NULL; } @@ -571,6 +602,7 @@ bool virNetServerClientGetReadonly(virNetServerClientPtr client) } +#ifdef HAVE_GNUTLS bool virNetServerClientHasTLSSession(virNetServerClientPtr client) { bool has; @@ -589,6 +621,7 @@ int virNetServerClientGetTLSKeySize(virNetServerClientPtr client) virNetServerClientUnlock(client); return size; } +#endif int virNetServerClientGetFD(virNetServerClientPtr client) { @@ -615,8 +648,10 @@ bool virNetServerClientIsSecure(virNetServerClientPtr client) { bool secure = false; virNetServerClientLock(client); +#if HAVE_GNUTLS if (client->tls) secure = true; +#endif #if HAVE_SASL if (client->sasl) secure = true; @@ -628,6 +663,7 @@ bool virNetServerClientIsSecure(virNetServerClientPtr client) } + #if HAVE_SASL void virNetServerClientSetSASLSession(virNetServerClientPtr client, virNetSASLSessionPtr sasl) @@ -730,8 +766,10 @@ void virNetServerClientDispose(void *obj) #endif if (client->sockTimer > 0) virEventRemoveTimeout(client->sockTimer); +#if HAVE_GNUTLS virObjectUnref(client->tls); virObjectUnref(client->tlsCtxt); +#endif virObjectUnref(client->sock); virNetServerClientUnlock(client); virMutexDestroy(&client->lock); @@ -784,10 +822,12 @@ void virNetServerClientClose(virNetServerClientPtr client) if (client->sock) virNetSocketRemoveIOCallback(client->sock); +#if HAVE_GNUTLS if (client->tls) { virObjectUnref(client->tls); client->tls = NULL; } +#endif client->wantClose = true; while (client->rx) { @@ -847,10 +887,13 @@ int virNetServerClientInit(virNetServerClientPtr client) { virNetServerClientLock(client); +#if HAVE_GNUTLS if (!client->tlsCtxt) { +#endif /* Plain socket, so prepare to read first message */ if (virNetServerClientRegisterEvent(client) < 0) goto error; +#if HAVE_GNUTLS } else { int ret; @@ -879,6 +922,7 @@ int virNetServerClientInit(virNetServerClientPtr client) goto error; } } +#endif virNetServerClientUnlock(client); return 0; @@ -1180,6 +1224,8 @@ virNetServerClientDispatchWrite(virNetServerClientPtr client) } } + +#if HAVE_GNUTLS static void virNetServerClientDispatchHandshake(virNetServerClientPtr client) { @@ -1202,6 +1248,7 @@ virNetServerClientDispatchHandshake(virNetServerClientPtr client) client->wantClose = true; } } +#endif static void virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque) @@ -1218,17 +1265,21 @@ virNetServerClientDispatchEvent(virNetSocketPtr sock, int events, void *opaque) if (events & (VIR_EVENT_HANDLE_WRITABLE | VIR_EVENT_HANDLE_READABLE)) { +#if HAVE_GNUTLS if (client->tls && virNetTLSSessionGetHandshakeStatus(client->tls) != VIR_NET_TLS_HANDSHAKE_COMPLETE) { virNetServerClientDispatchHandshake(client); } else { +#endif if (events & VIR_EVENT_HANDLE_WRITABLE) virNetServerClientDispatchWrite(client); if (events & VIR_EVENT_HANDLE_READABLE && client->rx) virNetServerClientDispatchRead(client); +#if HAVE_GNUTLS } +#endif } /* NB, will get HANGUP + READABLE at same time upon diff --git a/src/rpc/virnetserverclient.h b/src/rpc/virnetserverclient.h index 65084e2..b11b9a9 100644 --- a/src/rpc/virnetserverclient.h +++ b/src/rpc/virnetserverclient.h @@ -52,7 +52,9 @@ virNetServerClientPtr virNetServerClientNew(virNetSocketPtr sock, int auth, bool readonly, size_t nrequests_max, +# ifdef HAVE_GNUTLS virNetTLSContextPtr tls, +# endif virNetServerClientPrivNew privNew, virNetServerClientPrivPreExecRestart privPreExecRestart, virFreeCallback privFree, @@ -76,8 +78,10 @@ void virNetServerClientRemoveFilter(virNetServerClientPtr client, int virNetServerClientGetAuth(virNetServerClientPtr client); bool virNetServerClientGetReadonly(virNetServerClientPtr client); +# ifdef HAVE_GNUTLS bool virNetServerClientHasTLSSession(virNetServerClientPtr client); int virNetServerClientGetTLSKeySize(virNetServerClientPtr client); +# endif # ifdef HAVE_SASL void virNetServerClientSetSASLSession(virNetServerClientPtr client, diff --git a/src/rpc/virnetserverservice.c b/src/rpc/virnetserverservice.c index 7d671f0..61dd682 100644 --- a/src/rpc/virnetserverservice.c +++ b/src/rpc/virnetserverservice.c @@ -41,7 +41,9 @@ struct _virNetServerService { bool readonly; size_t nrequests_client_max; +#if HAVE_GNUTLS virNetTLSContextPtr tls; +#endif virNetServerServiceDispatchFunc dispatchFunc; void *dispatchOpaque; @@ -90,9 +92,11 @@ cleanup: virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename, const char *service, int auth, +#if HAVE_GNUTLS + virNetTLSContextPtr tls, +#endif bool readonly, - size_t nrequests_client_max, - virNetTLSContextPtr tls) + size_t nrequests_client_max) { virNetServerServicePtr svc; size_t i; @@ -106,7 +110,9 @@ virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename, svc->auth = auth; svc->readonly = readonly; svc->nrequests_client_max = nrequests_client_max; +#if HAVE_GNUTLS svc->tls = virObjectRef(tls); +#endif if (virNetSocketNewListenTCP(nodename, service, @@ -144,9 +150,11 @@ virNetServerServicePtr virNetServerServiceNewUNIX(const char *path, mode_t mask, gid_t grp, int auth, +#if HAVE_GNUTLS + virNetTLSContextPtr tls, +#endif bool readonly, - size_t nrequests_client_max, - virNetTLSContextPtr tls) + size_t nrequests_client_max) { virNetServerServicePtr svc; int i; @@ -160,7 +168,9 @@ virNetServerServicePtr virNetServerServiceNewUNIX(const char *path, svc->auth = auth; svc->readonly = readonly; svc->nrequests_client_max = nrequests_client_max; +#if HAVE_GNUTLS svc->tls = virObjectRef(tls); +#endif svc->nsocks = 1; if (VIR_ALLOC_N(svc->socks, svc->nsocks) < 0) @@ -202,9 +212,11 @@ error: virNetServerServicePtr virNetServerServiceNewFD(int fd, int auth, +#if HAVE_GNUTLS + virNetTLSContextPtr tls, +#endif bool readonly, - size_t nrequests_client_max, - virNetTLSContextPtr tls) + size_t nrequests_client_max) { virNetServerServicePtr svc; int i; @@ -218,7 +230,9 @@ virNetServerServicePtr virNetServerServiceNewFD(int fd, svc->auth = auth; svc->readonly = readonly; svc->nrequests_client_max = nrequests_client_max; +#if HAVE_GNUTLS svc->tls = virObjectRef(tls); +#endif svc->nsocks = 1; if (VIR_ALLOC_N(svc->socks, svc->nsocks) < 0) @@ -401,11 +415,12 @@ size_t virNetServerServiceGetMaxRequests(virNetServerServicePtr svc) return svc->nrequests_client_max; } +#if HAVE_GNUTLS virNetTLSContextPtr virNetServerServiceGetTLSContext(virNetServerServicePtr svc) { return svc->tls; } - +#endif void virNetServerServiceSetDispatcher(virNetServerServicePtr svc, virNetServerServiceDispatchFunc func, @@ -425,7 +440,9 @@ void virNetServerServiceDispose(void *obj) virObjectUnref(svc->socks[i]); VIR_FREE(svc->socks); +#if HAVE_GNUTLS virObjectUnref(svc->tls); +#endif } void virNetServerServiceToggle(virNetServerServicePtr svc, diff --git a/src/rpc/virnetserverservice.h b/src/rpc/virnetserverservice.h index 615b572..934b8d3 100644 --- a/src/rpc/virnetserverservice.h +++ b/src/rpc/virnetserverservice.h @@ -40,21 +40,27 @@ typedef int (*virNetServerServiceDispatchFunc)(virNetServerServicePtr svc, virNetServerServicePtr virNetServerServiceNewTCP(const char *nodename, const char *service, int auth, +# if HAVE_GNUTLS + virNetTLSContextPtr tls, +# endif bool readonly, - size_t nrequests_client_max, - virNetTLSContextPtr tls); + size_t nrequests_client_max); virNetServerServicePtr virNetServerServiceNewUNIX(const char *path, mode_t mask, gid_t grp, int auth, +# if HAVE_GNUTLS + virNetTLSContextPtr tls, +# endif bool readonly, - size_t nrequests_client_max, - virNetTLSContextPtr tls); + size_t nrequests_client_max); virNetServerServicePtr virNetServerServiceNewFD(int fd, int auth, +# if HAVE_GNUTLS + virNetTLSContextPtr tls, +# endif bool readonly, - size_t nrequests_client_max, - virNetTLSContextPtr tls); + size_t nrequests_client_max); virNetServerServicePtr virNetServerServiceNewPostExecRestart(virJSONValuePtr object); @@ -65,7 +71,9 @@ int virNetServerServiceGetPort(virNetServerServicePtr svc); int virNetServerServiceGetAuth(virNetServerServicePtr svc); bool virNetServerServiceIsReadonly(virNetServerServicePtr svc); size_t virNetServerServiceGetMaxRequests(virNetServerServicePtr svc); +# ifdef HAVE_GNUTLS virNetTLSContextPtr virNetServerServiceGetTLSContext(virNetServerServicePtr svc); +# endif void virNetServerServiceSetDispatcher(virNetServerServicePtr svc, virNetServerServiceDispatchFunc func, diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index ef93892..a817999 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -79,7 +79,9 @@ struct _virNetSocket { char *localAddrStr; char *remoteAddrStr; +#if HAVE_GNUTLS virNetTLSSessionPtr tlsSession; +#endif #if HAVE_SASL virNetSASLSessionPtr saslSession; @@ -948,11 +950,13 @@ virJSONValuePtr virNetSocketPreExecRestart(virNetSocketPtr sock) goto error; } #endif +#if HAVE_GNUTLS if (sock->tlsSession) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Unable to save socket state when TLS session is active")); goto error; } +#endif if (!(object = virJSONValueNewObject())) goto error; @@ -1011,10 +1015,12 @@ void virNetSocketDispose(void *obj) unlink(sock->localAddr.data.un.sun_path); #endif +#if HAVE_GNUTLS /* Make sure it can't send any more I/O during shutdown */ if (sock->tlsSession) virNetTLSSessionSetIOCallbacks(sock->tlsSession, NULL, NULL, NULL); virObjectUnref(sock->tlsSession); +#endif #if HAVE_SASL virObjectUnref(sock->saslSession); #endif @@ -1178,6 +1184,7 @@ const char *virNetSocketRemoteAddrString(virNetSocketPtr sock) } +#if HAVE_GNUTLS static ssize_t virNetSocketTLSSessionWrite(const char *buf, size_t len, void *opaque) @@ -1208,7 +1215,7 @@ void virNetSocketSetTLSSession(virNetSocketPtr sock, sock); virMutexUnlock(&sock->lock); } - +#endif #if HAVE_SASL void virNetSocketSetSASLSession(virNetSocketPtr sock, @@ -1280,13 +1287,17 @@ static ssize_t virNetSocketReadWire(virNetSocketPtr sock, char *buf, size_t len) #endif reread: +#if HAVE_GNUTLS if (sock->tlsSession && virNetTLSSessionGetHandshakeStatus(sock->tlsSession) == VIR_NET_TLS_HANDSHAKE_COMPLETE) { ret = virNetTLSSessionRead(sock->tlsSession, buf, len); } else { +#endif ret = read(sock->fd, buf, len); +#if HAVE_GNUTLS } +#endif if ((ret < 0) && (errno == EINTR)) goto reread; @@ -1335,13 +1346,17 @@ static ssize_t virNetSocketWriteWire(virNetSocketPtr sock, const char *buf, size #endif rewrite: +#if HAVE_GNUTLS if (sock->tlsSession && virNetTLSSessionGetHandshakeStatus(sock->tlsSession) == VIR_NET_TLS_HANDSHAKE_COMPLETE) { ret = virNetTLSSessionWrite(sock->tlsSession, buf, len); } else { +#endif ret = write(sock->fd, buf, len); +#if HAVE_GNUTLS } +#endif if (ret < 0) { if (errno == EINTR) diff --git a/src/rpc/virnetsocket.h b/src/rpc/virnetsocket.h index 7016c09..ce15bb8 100644 --- a/src/rpc/virnetsocket.h +++ b/src/rpc/virnetsocket.h @@ -26,7 +26,9 @@ # include "virsocketaddr.h" # include "vircommand.h" -# include "virnettlscontext.h" +# ifdef HAVE_GNUTLS +# include "virnettlscontext.h" +# endif # include "virobject.h" # ifdef HAVE_SASL # include "virnetsaslcontext.h" @@ -122,8 +124,10 @@ ssize_t virNetSocketWrite(virNetSocketPtr sock, const char *buf, size_t len); int virNetSocketSendFD(virNetSocketPtr sock, int fd); int virNetSocketRecvFD(virNetSocketPtr sock, int *fd); +# ifdef HAVE_GNUTLS void virNetSocketSetTLSSession(virNetSocketPtr sock, virNetTLSSessionPtr sess); +# endif # ifdef HAVE_SASL void virNetSocketSetSASLSession(virNetSocketPtr sock, diff --git a/tests/Makefile.am b/tests/Makefile.am index b603ea3..9c7c6fb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -91,7 +91,7 @@ test_programs = virshtest sockettest \ commandtest seclabeltest \ virhashtest virnetmessagetest virnetsockettest \ viratomictest \ - utiltest virnettlscontexttest shunloadtest \ + utiltest shunloadtest \ virtimetest viruritest virkeyfiletest \ virauthconfigtest \ virbitmaptest \ @@ -100,6 +100,10 @@ test_programs = virshtest sockettest \ sysinfotest \ $(NULL) +if HAVE_GNUTLS +test_programs += virnettlscontexttest +endif + if WITH_SECDRIVER_SELINUX test_programs += securityselinuxtest endif @@ -526,6 +530,7 @@ virnetsockettest_SOURCES = \ virnetsockettest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS) virnetsockettest_LDADD = $(LDADDS) +if HAVE_GNUTLS virnettlscontexttest_SOURCES = \ virnettlscontexttest.c testutils.h testutils.c virnettlscontexttest_CFLAGS = -Dabs_builddir="\"$(abs_builddir)\"" $(AM_CFLAGS) @@ -536,6 +541,10 @@ virnettlscontexttest_LDADD += -ltasn1 else EXTRA_DIST += pkix_asn1_tab.c endif +else +EXTRA_DIST += \ + virnettlscontexttest.c testutils.h testutils.c pkix_asn1_tab.c +endif virtimetest_SOURCES = \ virtimetest.c testutils.h testutils.c -- 1.8.0.1

On 01/07/2013 08:24 AM, Daniel P. Berrange wrote:
From: "Daniel P. Berrange" <berrange@redhat.com>
Add checks for existance of GNUTLS and automatically disable
s/existance/existence/
it if not found.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- configure.ac | 70 ++++++++++++++++++++++++++++++++----------- daemon/libvirtd.c | 41 ++++++++++++++++++------- daemon/remote.c | 2 ++ src/Makefile.am | 8 ++++- src/libvirt.c | 17 ++++++++--- src/locking/lock_daemon.c | 12 ++++++-- src/lxc/lxc_controller.c | 6 ++-- src/qemu/qemu_migration.c | 15 ++++++++-- src/remote/remote_driver.c | 15 ++++++++++ src/rpc/virnetclient.c | 20 ++++++++++--- src/rpc/virnetclient.h | 8 ++++- src/rpc/virnetserver.c | 6 ++++ src/rpc/virnetserver.h | 6 +++- src/rpc/virnetserverclient.c | 63 ++++++++++++++++++++++++++++++++++---- src/rpc/virnetserverclient.h | 4 +++ src/rpc/virnetserverservice.c | 31 ++++++++++++++----- src/rpc/virnetserverservice.h | 20 +++++++++---- src/rpc/virnetsocket.c | 17 ++++++++++- src/rpc/virnetsocket.h | 6 +++- tests/Makefile.am | 11 ++++++- 20 files changed, 311 insertions(+), 67 deletions(-)
Touches quite a bit, but hopefully for the better. What platform are you targeting where you were unwilling to require gnutls as a prereq?
+++ b/configure.ac @@ -1025,30 +1025,62 @@ CFLAGS="$old_cflags" LIBS="$old_libs"
dnl GnuTLS library -GNUTLS_CFLAGS= -GNUTLS_LIBS= -GNUTLS_FOUND=no -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 +AC_ARG_WITH([gnutls], + AC_HELP_STRING([--with-gnutls], [use GNUTLS for encryption @<:@default=check@:>@]), + [], + [with_gnutls=check]) + + +if test "x$with_gnutls" != "xno"; then + if test "x$with_gnutls" != "xyes" && test "x$with_gnutls" != "xcheck"; then + GNUTLS_CFLAGS="-I$with_gnutls/include" + GNUTLS_LIBS="-L$with_gnutls/lib" + fi fail=0 + old_cflags="$CFLAGS" old_libs="$LIBS" - AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1]) - AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt]) + CFLAGS="$CFLAGS $GNUTLS_CFLAGS" + LIBS="$LIBS $GNUTLS_LIBS"
- test $fail = 1 && - AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt]) + GNUTLS_FOUND=no + 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 + fail=0 + AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1]) + AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt]) + + test $fail = 0 && GNUTLS_FOUND=yes + + GNUTLS_LIBS="$GNUTLS_LIBS -lgnutls"
It looks fishy requiring -lgcrypt for the probe, but not using it here...
+ fi + if test "$GNUTLS_FOUND" = "no"; then + if test "$with_gnutls" = "check"; then + with_gnutls=no + GNUTLS_LIBS= + GNUTLS_CFLAGS= + else + AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt]) + fi + else + 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="$GNUTLS_LIBS -lgcrypt"
...but then you unconditionally add it in later. I guess that's okay.
+++ b/daemon/libvirtd.c @@ -449,7 +449,9 @@ static int daemonSetupNetworking(virNetServerPtr srv, virNetServerServicePtr svc = NULL; virNetServerServicePtr svcRO = NULL; virNetServerServicePtr svcTCP = NULL; +#if HAVE_GNUTLS virNetServerServicePtr svcTLS = NULL; +#endif
This makes for a lot of #ifdef'd code, and I'm worried that we might get out of sync depending on whether gnutls is present or not. Would it be any easier to always declare this variable, but always have it NULL when tls is not present?
gid_t unix_sock_gid = 0; int unix_sock_ro_mask = 0; int unix_sock_rw_mask = 0; @@ -474,9 +476,11 @@ static int daemonSetupNetworking(virNetServerPtr srv, unix_sock_rw_mask, unix_sock_gid, config->auth_unix_rw, +#if HAVE_GNUTLS + NULL, +#endif
Likewise, having different signatures based on the #ifdef seems awkward, compared to making the conditional code just ignore the parameter when tls is not present. That said, this is not the first time we've done this (the code for HAVE_SASL is equally if-def'd), so I guess I can live with it.
#if HAVE_SASL if (config->auth_unix_rw == REMOTE_AUTH_SASL || config->auth_unix_ro == REMOTE_AUTH_SASL || - config->auth_tcp == REMOTE_AUTH_SASL || - config->auth_tls == REMOTE_AUTH_SASL) { +# if HAVE_GNUTLS + config->auth_tls == REMOTE_AUTH_SASL || +# endif
Indeed, the fact that this code is nested #ifdefs explains why you are forced to follow the same style as HAVE_SASL for lots of conditional signature.
+++ b/src/locking/lock_daemon.c @@ -654,7 +654,11 @@ virLockDaemonSetupNetworkingSystemD(virNetServerPtr srv)
/* Systemd passes FDs, starting immediately after stderr, * so the first FD we'll get is '3'. */ - if (!(svc = virNetServerServiceNewFD(3, 0, false, 1, NULL))) + if (!(svc = virNetServerServiceNewFD(3, 0, +#if HAVE_GNUTLS + NULL, +#endif + false, 1)))
Still, I'm not a fan of mid-function-call #ifdefs. It does not play nicely with turning a function call into a macro call. And you're forced to reflect your #ifdef choice outside of src/rpc, which feels like a leaky abstraction. Are you sure you want the conditional signature?
+++ b/src/qemu/qemu_migration.c @@ -23,8 +23,10 @@ #include <config.h>
#include <sys/time.h> -#include <gnutls/gnutls.h> -#include <gnutls/x509.h> +#ifdef HAVE_GNUTLS +# include <gnutls/gnutls.h> +# include <gnutls/x509.h> +#endif
Also, can we wrap this inside a "virtls.h" convenience header, so that all other files outside of src/rpc (or src/util) can unconditionally include one header, instead of having to worry about HAVE_GNUTLS? Overall, your patch looks sane, and you have a 'weak ACK' - that is, I'm willing to look the other way and let this patch go in, if you don't think it is worth even more refactoring to avoid quite so much leaky #ifdef throughout the code base. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Mon, Jan 07, 2013 at 05:37:30PM -0700, Eric Blake wrote:
Touches quite a bit, but hopefully for the better. What platform are you targeting where you were unwilling to require gnutls as a prereq?
No specific platform as such, just that if you build with --without-remote and --without-libvirtd we should not be mandating use of gnutls. Various people have asked for this feature over the years, so I think it is worth it.
Overall, your patch looks sane, and you have a 'weak ACK' - that is, I'm willing to look the other way and let this patch go in, if you don't think it is worth even more refactoring to avoid quite so much leaky #ifdef throughout the code base.
Basically I'm following the approach used for SASL. It would be nice to try and adapt virnet{tls,sasl}context.c so that all the functions still exist, but have no-op impls, but that's much more work - I've tried it before with SASL but never got a satisfactory result Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 01/08/2013 01:47 PM, Daniel P. Berrange wrote:
On Mon, Jan 07, 2013 at 05:37:30PM -0700, Eric Blake wrote:
Touches quite a bit, but hopefully for the better. What platform are you targeting where you were unwilling to require gnutls as a prereq?
No specific platform as such, just that if you build with --without-remote and --without-libvirtd we should not be mandating use of gnutls. Various people have asked for this feature over the years, so I think it is worth it.
Overall, your patch looks sane, and you have a 'weak ACK' - that is, I'm willing to look the other way and let this patch go in, if you don't think it is worth even more refactoring to avoid quite so much leaky #ifdef throughout the code base.
Basically I'm following the approach used for SASL. It would be nice to try and adapt virnet{tls,sasl}context.c so that all the functions still exist, but have no-op impls, but that's much more work - I've tried it before with SASL but never got a satisfactory result
As it is, with your patch, I just got this failure on RHEL 5: /usr/bin/perl ./check-symfile.pl l ibvirt.yms \ .libs/libvirt.so Expected symbol virNetServerClientGetTLSKeySize is not in ELF library ... I still need to do more investigation, but it makes me wonder if we got the conditional symfile manipulation correct? -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Tue, Jan 08, 2013 at 04:30:49PM -0700, Eric Blake wrote:
On 01/08/2013 01:47 PM, Daniel P. Berrange wrote:
On Mon, Jan 07, 2013 at 05:37:30PM -0700, Eric Blake wrote:
Touches quite a bit, but hopefully for the better. What platform are you targeting where you were unwilling to require gnutls as a prereq?
No specific platform as such, just that if you build with --without-remote and --without-libvirtd we should not be mandating use of gnutls. Various people have asked for this feature over the years, so I think it is worth it.
Overall, your patch looks sane, and you have a 'weak ACK' - that is, I'm willing to look the other way and let this patch go in, if you don't think it is worth even more refactoring to avoid quite so much leaky #ifdef throughout the code base.
Basically I'm following the approach used for SASL. It would be nice to try and adapt virnet{tls,sasl}context.c so that all the functions still exist, but have no-op impls, but that's much more work - I've tried it before with SASL but never got a satisfactory result
As it is, with your patch, I just got this failure on RHEL 5:
/usr/bin/perl ./check-symfile.pl l ibvirt.yms \ .libs/libvirt.so Expected symbol virNetServerClientGetTLSKeySize is not in ELF library ...
I still need to do more investigation, but it makes me wonder if we got the conditional symfile manipulation correct?
Yeah, actually I think that's something I forgot to handle. That said on RHEL5, GNUTLS should be present so that symbol ought to have been built, unless you were testing with --without-gnutls perhaps ? Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On 01/09/2013 02:48 AM, Daniel P. Berrange wrote:
As it is, with your patch, I just got this failure on RHEL 5:
/usr/bin/perl ./check-symfile.pl l ibvirt.yms \ .libs/libvirt.so Expected symbol virNetServerClientGetTLSKeySize is not in ELF library ...
I still need to do more investigation, but it makes me wonder if we got the conditional symfile manipulation correct?
Yeah, actually I think that's something I forgot to handle.
We still need to fix that for when a user explicitly configures --without-gnutls.
on RHEL5, GNUTLS should be present so that symbol ought to have been built, unless you were testing with --without-gnutls perhaps ?
Figured it out: on RHEL 5, automake and autoconf are so old that they don't automatically reconfigure when you use just 'make', so config.h was out of date, and the new HAVE_GNUTLS macro wasn't defined. Forcing a fresh reconfigure fixed the issue to use gnutls in a default build. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Daniel P. Berrange
-
Eric Blake