From patchwork Wed May 2 19:32:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Moore X-Patchwork-Id: 156541 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id A89E7B6FB7 for ; Thu, 3 May 2012 05:33:11 +1000 (EST) Received: from localhost ([::1]:37306 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPfIS-0002j1-Om for incoming@patchwork.ozlabs.org; Wed, 02 May 2012 15:33:08 -0400 Received: from eggs.gnu.org ([208.118.235.92]:32882) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPfIL-0002iw-Kl for qemu-devel@nongnu.org; Wed, 02 May 2012 15:33:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SPfIJ-00083a-Mu for qemu-devel@nongnu.org; Wed, 02 May 2012 15:33:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23356) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPfIJ-00083Q-EH for qemu-devel@nongnu.org; Wed, 02 May 2012 15:32:59 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q42JWv0d028374 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 2 May 2012 15:32:57 -0400 Received: from [127.0.0.1] (dhcp-187-49.bos.redhat.com [10.16.187.49]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q42JWupB011560; Wed, 2 May 2012 15:32:57 -0400 To: qemu-devel@nongnu.org From: Paul Moore Date: Wed, 02 May 2012 15:32:56 -0400 Message-ID: <20120502193256.6508.86360.stgit@sifl> User-Agent: StGit/0.16 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2] vnc: disable VNC password authentication (security type 2) when in FIPS mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org FIPS 140-2 requires disabling certain ciphers, including DES, which is used by VNC to obscure passwords when they are sent over the network. The solution for FIPS users is to disable the use of VNC password auth when the host system is operating in FIPS mode. This patch causes qemu to emit a syslog entry indicating that VNC password auth is disabled when it detects the host is running in FIPS mode, and unless a VNC password was specified on the command line it continues normally. However, if a VNC password was given on the command line, qemu fails with an error message to stderr explaining that VNC password auth is not allowed in FIPS mode. Signed-off-by: Paul Moore --- Changelog * v2 - Protected syslog with _WIN32 - Protected the guts of fips_enabled() with __linux__ - Converted fips_enabled() and the fips flag from int to bool *v1 - Initial draft --- qemu-doc.texi | 8 +++++--- ui/vnc.c | 39 +++++++++++++++++++++++++++++++++++++++ ui/vnc.h | 1 + 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/qemu-doc.texi b/qemu-doc.texi index e5d7ac4..f9b113e 100644 --- a/qemu-doc.texi +++ b/qemu-doc.texi @@ -1124,9 +1124,11 @@ the protocol limits passwords to 8 characters it should not be considered to provide high security. The password can be fairly easily brute-forced by a client making repeat connections. For this reason, a VNC server using password authentication should be restricted to only listen on the loopback interface -or UNIX domain sockets. Password authentication is requested with the @code{password} -option, and then once QEMU is running the password is set with the monitor. Until -the monitor is used to set the password all clients will be rejected. +or UNIX domain sockets. Password authentication is not supported when operating +in FIPS 140-2 compliance mode as it requires the use of the DES cipher. Password +authentication is requested with the @code{password} option, and then once QEMU +is running the password is set with the monitor. Until the monitor is used to +set the password all clients will be rejected. @example qemu [...OPTIONS...] -vnc :1,password -monitor stdio diff --git a/ui/vnc.c b/ui/vnc.c index deb9ecd..6162425 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -32,6 +32,9 @@ #include "acl.h" #include "qemu-objects.h" #include "qmp-commands.h" +#ifndef _WIN32 +#include +#endif #define VNC_REFRESH_INTERVAL_BASE 30 #define VNC_REFRESH_INTERVAL_INC 50 @@ -48,6 +51,27 @@ static DisplayChangeListener *dcl; static int vnc_cursor_define(VncState *vs); static void vnc_release_modifiers(VncState *vs); +static bool fips_enabled(void) +{ + bool enabled = false; + +#ifdef __linux__ + FILE *fds; + char value; + + fds = fopen("/proc/sys/crypto/fips_enabled", "r"); + if (fds == NULL) { + return false; + } + if (fread(&value, sizeof(value), 1, fds) == 1 && value == '1') { + enabled = true; + } + fclose(fds); +#endif /* __linux__ */ + + return enabled; +} + static void vnc_set_share_mode(VncState *vs, VncShareMode mode) { #ifdef _VNC_DEBUG @@ -2748,6 +2772,14 @@ void vnc_display_init(DisplayState *ds) dcl->idle = 1; vnc_display = vs; + vs->fips = fips_enabled(); + VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled")); +#ifndef _WIN32 + if (vs->fips) { + syslog(LOG_NOTICE, "Disabling VNC password auth due to FIPS mode\n"); + } +#endif /* _WIN32 */ + vs->lsock = -1; vs->ds = ds; @@ -2892,6 +2924,13 @@ int vnc_display_open(DisplayState *ds, const char *display) while ((options = strchr(options, ','))) { options++; if (strncmp(options, "password", 8) == 0) { + if (vs->fips) { + fprintf(stderr, + "VNC password auth disabled due to FIPS mode\n"); + g_free(vs->display); + vs->display = NULL; + return -1; + } password = 1; /* Require password auth */ } else if (strncmp(options, "reverse", 7) == 0) { reverse = 1; diff --git a/ui/vnc.h b/ui/vnc.h index a851ebd..d41631b 100644 --- a/ui/vnc.h +++ b/ui/vnc.h @@ -160,6 +160,7 @@ struct VncDisplay char *display; char *password; time_t expires; + bool fips; int auth; bool lossy; bool non_adaptive;