Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 804

kvm-83-270.el5_11.src.rpm

From 40632665feb29edb15e43d3f56581ad14f52a0c7 Mon Sep 17 00:00:00 2001
Message-Id: <40632665feb29edb15e43d3f56581ad14f52a0c7.1346769658.git.minovotn@redhat.com>
From: Paul Moore <pmoore@redhat.com>
Date: Thu, 9 Aug 2012 17:52:33 +0200
Subject: [PATCH] vnc: disable VNC password authentication (security type 2)
 when in FIPS mode

RH-Author: Paul Moore <pmoore@redhat.com>
Message-id: <20120809175233.20568.32711.stgit@sifl>
Patchwork-id: 40654
O-Subject: [RHEL-5.8.z RHEL-5.9 qemu-kvm PATCH] vnc: disable VNC password authentication (security type 2) when in FIPS mode
Bugzilla: 805676
RH-Acked-by: Eric Blake <eblake@redhat.com>
RH-Acked-by: Daniel P. Berrange <berrange@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>

Upstream: 0f66998ff6d5d2133b9b08471a44e13b11119e50
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=805676
Brew: https://brewweb.devel.redhat.com/taskinfo?taskID=4741867

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 compliance mode.  This patch diverges
slightly from the upstream patch merged on August 3rd, 2012 as we do away
with the need for the "-enable-fips" command line option and enter FIPS
compliance mode automatically when the host kernel has been booted into
FIPS compliance mode.

This patch causes QEMU to emit a message to stderr when the host system is
running in FIPS mode and a VNC password was specified on the commend line.
If the system is not running in FIPS mode, or is running in FIPS mode but
VNC password authentication was not requested, QEMU operates normally.

Signed-off-by: Paul Moore <pmoore@redhat.com>
---
 qemu/Makefile      |    4 ++--
 qemu/fips.c        |   40 ++++++++++++++++++++++++++++++++++++++++
 qemu/fips.h        |   16 ++++++++++++++++
 qemu/qemu-doc.texi |    8 +++++---
 qemu/vl.c          |    2 ++
 qemu/vnc.c         |   18 +++++++++++++++---
 6 files changed, 80 insertions(+), 8 deletions(-)
 create mode 100644 qemu/fips.c
 create mode 100644 qemu/fips.h

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 qemu/Makefile      |  4 ++--
 qemu/fips.c        | 40 ++++++++++++++++++++++++++++++++++++++++
 qemu/fips.h        | 16 ++++++++++++++++
 qemu/qemu-doc.texi |  8 +++++---
 qemu/vl.c          |  2 ++
 qemu/vnc.c         | 18 +++++++++++++++---
 6 files changed, 80 insertions(+), 8 deletions(-)
 create mode 100644 qemu/fips.c
 create mode 100644 qemu/fips.h

diff --git a/qemu/Makefile b/qemu/Makefile
index c8a23e5..7554ba0 100644
--- a/qemu/Makefile
+++ b/qemu/Makefile
@@ -74,7 +74,7 @@ endif
 # CPUs and machines.
 
 OBJS=$(BLOCK_OBJS)
-OBJS+=readline.o console.o
+OBJS+=readline.o console.o fips.o
 
 OBJS+=irq.o
 OBJS+=i2c.o smbus.o smbus_eeprom.o
@@ -205,7 +205,7 @@ cocoa.o: cocoa.m
 sdl.o: sdl.c keymaps.c sdl_keysym.h
 	$(call quiet-command,$(CC) $(CFLAGS) $(CPPFLAGS) $(SDL_CFLAGS) -c -o $@ $<,"  CC     $@")
 
-vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h
+vnc.o: vnc.c keymaps.c sdl_keysym.h vnchextile.h fips.h
 	$(call quiet-command,$(CC) $(CFLAGS) $(CPPFLAGS) $(CONFIG_VNC_TLS_CFLAGS) -c -o $@ $<,"  CC     $@")
 
 curses.o: curses.c keymaps.c curses_keys.h
diff --git a/qemu/fips.c b/qemu/fips.c
new file mode 100644
index 0000000..5cb7770
--- /dev/null
+++ b/qemu/fips.c
@@ -0,0 +1,40 @@
+/*
+ * FIPS 140 compliance
+ *
+ * Copyright (c) 2012 Red Hat <pmoore@redhat.com>
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "fips.h"
+
+static bool fips_enabled = false;
+
+void fips_set_state(bool requested)
+{
+#ifdef __linux__
+    if (requested) {
+        FILE *fds = fopen("/proc/sys/crypto/fips_enabled", "r");
+        if (fds != NULL) {
+            fips_enabled = (fgetc(fds) == '1');
+            fclose(fds);
+        }
+    }
+#else
+    fips_enabled = false;
+#endif /* __linux__ */
+
+#ifdef _FIPS_DEBUG
+    fprintf(stderr, "FIPS mode %s (requested %s)\n",
+           (fips_enabled ? "enabled" : "disabled"),
+           (requested ? "enabled" : "disabled"));
+#endif
+}
+
+bool fips_get_state(void)
+{
+    return fips_enabled;
+}
diff --git a/qemu/fips.h b/qemu/fips.h
new file mode 100644
index 0000000..648163c
--- /dev/null
+++ b/qemu/fips.h
@@ -0,0 +1,16 @@
+/*
+ * FIPS 140 compliance
+ *
+ * Copyright (c) 2012 Red Hat <pmoore@redhat.com>
+ *
+ */
+
+#ifndef _QEMU_FIPS_H
+#define _QEMU_FIPS_H
+
+#include <stdbool.h>
+
+void fips_set_state(bool requested);
+bool fips_get_state(void);
+
+#endif
diff --git a/qemu/qemu-doc.texi b/qemu/qemu-doc.texi
index fb4da85..45a9da6 100644
--- a/qemu/qemu-doc.texi
+++ b/qemu/qemu-doc.texi
@@ -1961,9 +1961,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/qemu/vl.c b/qemu/vl.c
index 27cde0c..7789755 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -47,6 +47,7 @@
 #include "kvm.h"
 #include "balloon.h"
 #include "qemu-kvm.h"
+#include "fips.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -6061,6 +6062,7 @@ int main(int argc, char **argv, char **envp)
             }
         }
     }
+    fips_set_state(true);
     current_machine = machine;
 
 #ifdef CONFIG_QXL
diff --git a/qemu/vnc.c b/qemu/vnc.c
index dde462a..21e712e 100644
--- a/qemu/vnc.c
+++ b/qemu/vnc.c
@@ -34,6 +34,7 @@
 
 #include "vnc_keysym.h"
 #include "keymaps.c"
+#include "fips.h"
 #include <gcrypt.h>
 
 #ifdef CONFIG_VNC_TLS
@@ -2564,9 +2565,11 @@ void vnc_display_init(DisplayState *ds)
         exit(1);
     }
 
-    if (gcry_cipher_open(&vs->des_cipher, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0)) {
-        fprintf(stderr, "libgcrypt DES cipher initialization error\n");
-        exit(1);
+    if (!fips_get_state()) {
+        if (gcry_cipher_open(&vs->des_cipher, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0)) {
+            fprintf(stderr, "libgcrypt DES cipher initialization error\n");
+            exit(1);
+         }
     }
 }
 
@@ -2687,6 +2690,15 @@ int vnc_display_open(DisplayState *ds, const char *display)
     while ((options = strchr(options, ','))) {
 	options++;
 	if (strncmp(options, "password", 8) == 0) {
+            if (fips_get_state()) {
+                fprintf(stderr,
+                        "VNC password auth disabled due to FIPS mode, "
+                        "consider using the VeNCrypt or SASL authentication "
+                        "methods as an alternative\n");
+                qemu_free(vs->display);
+                vs->display = NULL;
+                return -1;
+            }
 	    password = 1; /* Require password auth */
 	} else if (strncmp(options, "reverse", 7) == 0) {
 	    reverse = 1;
-- 
1.7.11.4