From bfe86c763a9ff1b481d799537ff0f0cf6740dfd1 Mon Sep 17 00:00:00 2001
From: Andrea Spadaccini <spadaccio@google.com>
Date: Tue, 6 Sep 2011 10:26:56 +0100
Subject: [PATCH] Added SPICE TLS option and related cert paths

Signed-off-by: Andrea Spadaccini <spadaccio@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/backend.py           |  4 ++++
 lib/bootstrap.py         |  2 ++
 lib/constants.py         | 12 +++++++++++-
 lib/hypervisor/hv_kvm.py | 12 +++++++++++-
 lib/tools/ensure_dirs.py |  4 ++++
 5 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/lib/backend.py b/lib/backend.py
index 36da855cc..5e50f2f37 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -196,6 +196,8 @@ def _BuildUploadFileList():
     constants.SSH_KNOWN_HOSTS_FILE,
     constants.VNC_PASSWORD_FILE,
     constants.RAPI_CERT_FILE,
+    constants.SPICE_CERT_FILE,
+    constants.SPICE_CACERT_FILE,
     constants.RAPI_USERS_FILE,
     constants.CONFD_HMAC_KEY,
     constants.CLUSTER_DOMAIN_SECRET_FILE,
@@ -411,6 +413,8 @@ def LeaveCluster(modify_ssh_setup):
   try:
     utils.RemoveFile(constants.CONFD_HMAC_KEY)
     utils.RemoveFile(constants.RAPI_CERT_FILE)
+    utils.RemoveFile(constants.SPICE_CERT_FILE)
+    utils.RemoveFile(constants.SPICE_CACERT_FILE)
     utils.RemoveFile(constants.NODED_CERT_FILE)
   except: # pylint: disable=W0702
     logging.exception("Error while removing cluster secrets")
diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index 733a8ba98..a058c568e 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -557,6 +557,8 @@ def SetupNodeDaemon(cluster_name, node, ssh_key_check):
   # either by being constants or by the checks above
   sshrunner.CopyFileToNode(node, constants.NODED_CERT_FILE)
   sshrunner.CopyFileToNode(node, constants.RAPI_CERT_FILE)
+  sshrunner.CopyFileToNode(node, constants.SPICE_CERT_FILE)
+  sshrunner.CopyFileToNode(node, constants.SPICE_CACERT_FILE)
   sshrunner.CopyFileToNode(node, constants.CONFD_HMAC_KEY)
   mycommand = ("%s stop-all; %s start %s -b %s" %
                (constants.DAEMON_UTIL, constants.DAEMON_UTIL, constants.NODED,
diff --git a/lib/constants.py b/lib/constants.py
index 13a1a07b9..c9e1c5c7f 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -139,6 +139,8 @@ CLUSTER_CONF_FILE = DATA_DIR + "/config.data"
 NODED_CERT_FILE = DATA_DIR + "/server.pem"
 RAPI_CERT_FILE = DATA_DIR + "/rapi.pem"
 CONFD_HMAC_KEY = DATA_DIR + "/hmac.key"
+SPICE_CERT_FILE = DATA_DIR + "/spice.pem"
+SPICE_CACERT_FILE = DATA_DIR + "/spice-ca.pem"
 CLUSTER_DOMAIN_SECRET_FILE = DATA_DIR + "/cluster-domain-secret"
 INSTANCE_STATUS_FILE = RUN_GANETI_DIR + "/instance-status"
 SSH_KNOWN_HOSTS_FILE = DATA_DIR + "/known_hosts"
@@ -172,7 +174,12 @@ WATCHER_GROUP_INSTANCE_STATUS_FILE = DATA_DIR + "/watcher.%s.instance-status"
 #: File containing Unix timestamp until which watcher should be paused
 WATCHER_PAUSEFILE = DATA_DIR + "/watcher.pause"
 
-ALL_CERT_FILES = frozenset([NODED_CERT_FILE, RAPI_CERT_FILE])
+ALL_CERT_FILES = frozenset([
+  NODED_CERT_FILE,
+  RAPI_CERT_FILE,
+  SPICE_CERT_FILE,
+  SPICE_CACERT_FILE,
+  ])
 
 MASTER_SOCKET = SOCKET_DIR + "/ganeti-master"
 
@@ -679,6 +686,7 @@ HV_KVM_SPICE_JPEG_IMG_COMPR = "spice_jpeg_wan_compression"
 HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR = "spice_zlib_glz_wan_compression"
 HV_KVM_SPICE_STREAMING_VIDEO_DETECTION = "spice_streaming_video"
 HV_KVM_SPICE_AUDIO_COMPR = "spice_playback_compression"
+HV_KVM_SPICE_USE_TLS = "spice_use_tls"
 HV_ACPI = "acpi"
 HV_PAE = "pae"
 HV_USE_BOOTLOADER = "use_bootloader"
@@ -730,6 +738,7 @@ HVS_PARAMETER_TYPES = {
   HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR: VTYPE_STRING,
   HV_KVM_SPICE_STREAMING_VIDEO_DETECTION: VTYPE_STRING,
   HV_KVM_SPICE_AUDIO_COMPR: VTYPE_BOOL,
+  HV_KVM_SPICE_USE_TLS: VTYPE_BOOL,
   HV_ACPI: VTYPE_BOOL,
   HV_PAE: VTYPE_BOOL,
   HV_USE_BOOTLOADER: VTYPE_BOOL,
@@ -1355,6 +1364,7 @@ HVC_DEFAULTS = {
     HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR: "",
     HV_KVM_SPICE_STREAMING_VIDEO_DETECTION: "",
     HV_KVM_SPICE_AUDIO_COMPR: True,
+    HV_KVM_SPICE_USE_TLS: False,
     HV_KVM_FLOPPY_IMAGE_PATH: "",
     HV_CDROM_IMAGE_PATH: "",
     HV_KVM_CDROM2_IMAGE_PATH: "",
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 15358a683..754efb4d7 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -432,6 +432,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       hv_base.ParamInSet(False,
         constants.HT_KVM_SPICE_VALID_VIDEO_STREAM_DETECTION_OPTIONS),
     constants.HV_KVM_SPICE_AUDIO_COMPR: hv_base.NO_CHECK,
+    constants.HV_KVM_SPICE_USE_TLS: hv_base.NO_CHECK,
     constants.HV_KVM_FLOPPY_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
     constants.HV_CDROM_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
     constants.HV_KVM_CDROM2_IMAGE_PATH: hv_base.OPT_FILE_CHECK,
@@ -1030,7 +1031,15 @@ class KVMHypervisor(hv_base.BaseHypervisor):
         # ValidateParameters checked it.
         spice_address = spice_bind
 
-      spice_arg = "addr=%s,port=%s" % (spice_address, instance.network_port)
+      spice_arg = "addr=%s" % spice_address
+      if hvp[constants.HV_KVM_SPICE_USE_TLS]:
+        spice_arg = "%s,tls-port=%s,x509-cacert-file=%s" % (spice_arg,
+            instance.network_port, constants.SPICE_CACERT_FILE)
+        spice_arg = "%s,x509-key-file=%s,x509-cert-file=%s" % (spice_arg,
+            constants.SPICE_CERT_FILE, constants.SPICE_CERT_FILE)
+      else:
+        spice_arg = "%s,port=%s" % (spice_arg, instance.network_port)
+
       if not hvp[constants.HV_KVM_SPICE_PASSWORD_FILE]:
         spice_arg = "%s,disable-ticketing" % spice_arg
 
@@ -1651,6 +1660,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
         constants.HV_KVM_SPICE_JPEG_IMG_COMPR,
         constants.HV_KVM_SPICE_ZLIB_GLZ_IMG_COMPR,
         constants.HV_KVM_SPICE_STREAMING_VIDEO_DETECTION,
+        constants.HV_KVM_SPICE_USE_TLS,
         ])
       for param in spice_additional_params:
         if hvparams[param]:
diff --git a/lib/tools/ensure_dirs.py b/lib/tools/ensure_dirs.py
index 7abcce2a2..3d65c8c69 100644
--- a/lib/tools/ensure_dirs.py
+++ b/lib/tools/ensure_dirs.py
@@ -209,6 +209,10 @@ def GetPaths():
      getent.masterd_gid, False),
     (constants.RAPI_CERT_FILE, FILE, 0440, getent.rapi_uid,
      getent.masterd_gid, False),
+    (constants.SPICE_CERT_FILE, FILE, 0440, getent.noded_uid,
+     getent.masterd_gid, False),
+    (constants.SPICE_CACERT_FILE, FILE, 0440, getent.noded_uid,
+     getent.masterd_gid, False),
     (constants.NODED_CERT_FILE, FILE, 0440, getent.masterd_uid,
      getent.masterd_gid, False),
     ]
-- 
GitLab