Sync upstream patches + drop unused patches

Resolves: bz#1985858
This commit is contained in:
Jan Grulich 2021-08-16 08:26:59 +02:00
parent 6117f862af
commit cd4f8eba50
8 changed files with 365 additions and 69 deletions

View File

@ -1,8 +1,17 @@
From dbf76d2ee8da157c2c2970c937bcc0ed9ef08a6f Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Tue, 25 May 2021 14:14:33 +0200
Subject: [PATCH] Let user know that a view-only password is not used
---
unix/vncpasswd/vncpasswd.cxx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx
index 16c925ee..6398121e 100644
index 3055223ef..8f3649fe9 100644
--- a/unix/vncpasswd/vncpasswd.cxx
+++ b/unix/vncpasswd/vncpasswd.cxx
@@ -150,6 +150,8 @@ int main(int argc, char** argv)
@@ -160,6 +160,8 @@ int main(int argc, char** argv)
char yesno[3];
if (fgets(yesno, 3, stdin) != NULL && (yesno[0] == 'y' || yesno[0] == 'Y')) {
obfuscatedReadOnly = readpassword();

View File

@ -1,32 +1,31 @@
diff --git a/common/rfb/Password.cxx b/common/rfb/Password.cxx
index e4a508c..f555c57 100644
--- a/common/rfb/Password.cxx
+++ b/common/rfb/Password.cxx
@@ -55,7 +55,7 @@ PlainPasswd::~PlainPasswd() {
void PlainPasswd::replaceBuf(char* b) {
if (buf)
- memset(buf, 0, strlen(buf));
+ memset(buf, 0, length ? length : strlen(buf));
CharArray::replaceBuf(b);
}
From 5d834359bef6727df82cf4f2c2f3f255145f7785 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Tue, 25 May 2021 14:18:48 +0200
Subject: [PATCH] CharArray: pre-fill empty array with zeroes
CharArray should always be null-terminated. There is a potential
scenario where this all might lead to crash. In Password we call
memset(), passing length of the array we get with strlen(), but
this won't return correct value when the array is not properly
null-terminated.
---
common/rfb/util.h | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/common/rfb/util.h b/common/rfb/util.h
index 3100f90..764692a 100644
index 3100f90fd..71caac426 100644
--- a/common/rfb/util.h
+++ b/common/rfb/util.h
@@ -51,16 +51,21 @@ namespace rfb {
CharArray() : buf(0) {}
@@ -52,14 +52,17 @@ namespace rfb {
CharArray(char* str) : buf(str) {} // note: assumes ownership
CharArray(size_t len) {
+ length = len;
buf = new char[len]();
+ memset(buf, 0, len);
}
~CharArray() {
- delete [] buf;
+ if (buf) {
+ delete [] buf;
+ buf = nullptr;
+ }
}
void format(const char *fmt, ...) __printf_attr(2, 3);
@ -35,7 +34,5 @@ index 3100f90..764692a 100644
- void replaceBuf(char* b) {delete [] buf; buf = b;}
+ void replaceBuf(char* b) {if (buf) delete [] buf; buf = b;}
char* buf;
+ size_t length = 0;
private:
CharArray(const CharArray&);
CharArray& operator=(const CharArray&);

View File

@ -1,7 +1,7 @@
From 6125695b80f6a43002f454786115b0a6c1730831 Mon Sep 17 00:00:00 2001
From: Jan Grulich <jgrulich@redhat.com>
Date: Mon, 17 May 2021 13:44:32 +0200
Subject: [PATCH] SELinux: Add missing compression and install policy to
Subject: [PATCH 1/2] SELinux: Add missing compression and install policy to
correct directory
---
@ -15,25 +15,24 @@ index 7497bf846..b23f20f60 100644
@@ -10,15 +10,18 @@
PREFIX=/usr
DATADIR=$(PREFIX)/share
-all: vncsession.pp
+all: vncsession.pp.bz2
+
+%.pp.bz2: %.pp
+ bzip2 -9 $^
%.pp: %.te
make -f $(DATADIR)/selinux/devel/Makefile $@
clean:
- rm -f *.pp
+ rm -f *.pp *.pp.bz2
rm -rf tmp
-install: vncsession.pp
- mkdir -p $(DESTDIR)$(DATADIR)/selinux/packages
- install vncsession.pp $(DESTDIR)$(DATADIR)/selinux/packages/vncsession.pp
+install: vncsession.pp.bz2
+ mkdir -p $(DESTDIR)$(DATADIR)/selinux/packages/targeted/
+ install vncsession.pp.bz2 $(DESTDIR)$(DATADIR)/selinux/packages/targeted/vncsession.pp.bz2

View File

@ -1,5 +1,175 @@
diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx
index 9900837..59d2086 100644
--- a/common/rfb/CSecurityTLS.cxx
+++ b/common/rfb/CSecurityTLS.cxx
@@ -210,26 +210,66 @@ void CSecurityTLS::setParam()
static const char kx_anon_priority[] = ":+ANON-ECDH:+ANON-DH";
int ret;
- char *prio;
- const char *err;
- prio = (char*)malloc(strlen(Security::GnuTLSPriority) +
- strlen(kx_anon_priority) + 1);
- if (prio == NULL)
- throw AuthFailureException("Not enough memory for GnuTLS priority string");
+ // Custom priority string specified?
+ if (strcmp(Security::GnuTLSPriority, "") != 0) {
+ char *prio;
+ const char *err;
- strcpy(prio, Security::GnuTLSPriority);
- if (anon)
+ prio = (char*)malloc(strlen(Security::GnuTLSPriority) +
+ strlen(kx_anon_priority) + 1);
+ if (prio == NULL)
+ throw AuthFailureException("Not enough memory for GnuTLS priority string");
+
+ strcpy(prio, Security::GnuTLSPriority);
+ if (anon)
+ strcat(prio, kx_anon_priority);
+
+ ret = gnutls_priority_set_direct(session, prio, &err);
+
+ free(prio);
+
+ if (ret != GNUTLS_E_SUCCESS) {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ vlog.error("GnuTLS priority syntax error at: %s", err);
+ throw AuthFailureException("gnutls_set_priority_direct failed");
+ }
+ } else if (anon) {
+ const char *err;
+
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ // gnutls_set_default_priority_appends() expects a normal priority string that
+ // doesn't start with ":".
+ ret = gnutls_set_default_priority_append(session, kx_anon_priority + 1, &err, 0);
+ if (ret != GNUTLS_E_SUCCESS) {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ vlog.error("GnuTLS priority syntax error at: %s", err);
+ throw AuthFailureException("gnutls_set_default_priority_append failed");
+ }
+#else
+ // We don't know what the system default priority is, so we guess
+ // it's what upstream GnuTLS has
+ static const char gnutls_default_priority[] = "NORMAL";
+ char *prio;
+
+ prio = (char*)malloc(strlen(gnutls_default_priority) +
+ strlen(kx_anon_priority) + 1);
+ if (prio == NULL)
+ throw AuthFailureException("Not enough memory for GnuTLS priority string");
+
+ strcpy(prio, gnutls_default_priority);
strcat(prio, kx_anon_priority);
- ret = gnutls_priority_set_direct(session, prio, &err);
+ ret = gnutls_priority_set_direct(session, prio, &err);
- free(prio);
+ free(prio);
- if (ret != GNUTLS_E_SUCCESS) {
- if (ret == GNUTLS_E_INVALID_REQUEST)
- vlog.error("GnuTLS priority syntax error at: %s", err);
- throw AuthFailureException("gnutls_set_priority_direct failed");
+ if (ret != GNUTLS_E_SUCCESS) {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ vlog.error("GnuTLS priority syntax error at: %s", err);
+ throw AuthFailureException("gnutls_set_priority_direct failed");
+ }
+#endif
}
if (anon) {
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx
index ef5d8c9..f32f87f 100644
--- a/common/rfb/SSecurityTLS.cxx
+++ b/common/rfb/SSecurityTLS.cxx
@@ -198,26 +198,66 @@ void SSecurityTLS::setParams(gnutls_session_t session)
static const char kx_anon_priority[] = ":+ANON-ECDH:+ANON-DH";
int ret;
- char *prio;
- const char *err;
- prio = (char*)malloc(strlen(Security::GnuTLSPriority) +
- strlen(kx_anon_priority) + 1);
- if (prio == NULL)
- throw AuthFailureException("Not enough memory for GnuTLS priority string");
+ // Custom priority string specified?
+ if (strcmp(Security::GnuTLSPriority, "") != 0) {
+ char *prio;
+ const char *err;
- strcpy(prio, Security::GnuTLSPriority);
- if (anon)
+ prio = (char*)malloc(strlen(Security::GnuTLSPriority) +
+ strlen(kx_anon_priority) + 1);
+ if (prio == NULL)
+ throw AuthFailureException("Not enough memory for GnuTLS priority string");
+
+ strcpy(prio, Security::GnuTLSPriority);
+ if (anon)
+ strcat(prio, kx_anon_priority);
+
+ ret = gnutls_priority_set_direct(session, prio, &err);
+
+ free(prio);
+
+ if (ret != GNUTLS_E_SUCCESS) {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ vlog.error("GnuTLS priority syntax error at: %s", err);
+ throw AuthFailureException("gnutls_set_priority_direct failed");
+ }
+ } else if (anon) {
+ const char *err;
+
+#if GNUTLS_VERSION_NUMBER >= 0x030603
+ // gnutls_set_default_priority_appends() expects a normal priority string that
+ // doesn't start with ":".
+ ret = gnutls_set_default_priority_append(session, kx_anon_priority + 1, &err, 0);
+ if (ret != GNUTLS_E_SUCCESS) {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ vlog.error("GnuTLS priority syntax error at: %s", err);
+ throw AuthFailureException("gnutls_set_default_priority_append failed");
+ }
+#else
+ // We don't know what the system default priority is, so we guess
+ // it's what upstream GnuTLS has
+ static const char gnutls_default_priority[] = "NORMAL";
+ char *prio;
+
+ prio = (char*)malloc(strlen(gnutls_default_priority) +
+ strlen(kx_anon_priority) + 1);
+ if (prio == NULL)
+ throw AuthFailureException("Not enough memory for GnuTLS priority string");
+
+ strcpy(prio, gnutls_default_priority);
strcat(prio, kx_anon_priority);
- ret = gnutls_priority_set_direct(session, prio, &err);
+ ret = gnutls_priority_set_direct(session, prio, &err);
- free(prio);
+ free(prio);
- if (ret != GNUTLS_E_SUCCESS) {
- if (ret == GNUTLS_E_INVALID_REQUEST)
- vlog.error("GnuTLS priority syntax error at: %s", err);
- throw AuthFailureException("gnutls_set_priority_direct failed");
+ if (ret != GNUTLS_E_SUCCESS) {
+ if (ret == GNUTLS_E_INVALID_REQUEST)
+ vlog.error("GnuTLS priority syntax error at: %s", err);
+ throw AuthFailureException("gnutls_set_priority_direct failed");
+ }
+#endif
}
#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx
index e623ab5..4987b29 100644
index 0666041..59deb78 100644
--- a/common/rfb/Security.cxx
+++ b/common/rfb/Security.cxx
@@ -52,7 +52,7 @@ static LogWriter vlog("Security");
@ -7,7 +177,22 @@ index e623ab5..4987b29 100644
StringParameter Security::GnuTLSPriority("GnuTLSPriority",
"GnuTLS priority string that controls the TLS sessions handshake algorithms",
- "NORMAL");
+ "@SYSTEM");
+ "");
#endif
Security::Security()
diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man
index 83621c0..4a0d20c 100644
--- a/unix/xserver/hw/vnc/Xvnc.man
+++ b/unix/xserver/hw/vnc/Xvnc.man
@@ -226,7 +226,9 @@ also be in PEM format.
.TP
.B \-GnuTLSPriority \fIpriority\fP
GnuTLS priority string that controls the TLS sessions handshake algorithms.
-See the GnuTLS manual for possible values. Default is \fBNORMAL\fP.
+See the GnuTLS manual for possible values. For GnuTLS < 3.6.3 the default
+value will be \fBNORMAL\fP to use upstream default. For newer versions
+of GnuTLS system-wide crypto policy will be used.
.
.TP
.B \-UseBlacklist

View File

@ -1,13 +1,120 @@
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx
index b946022..2daefa2 100644
index d5ef47e..ef5d8c9 100644
--- a/common/rfb/SSecurityTLS.cxx
+++ b/common/rfb/SSecurityTLS.cxx
@@ -186,7 +186,7 @@ void SSecurityTLS::setParams(gnutls_session_t session)
@@ -37,7 +37,23 @@
#include <rdr/TLSOutStream.h>
#include <gnutls/x509.h>
-#define DH_BITS 1024 /* XXX This should be configurable! */
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
+/* FFDHE (RFC-7919) 2048-bit parameters, PEM-encoded */
+static unsigned char ffdhe2048[] =
+ "-----BEGIN DH PARAMETERS-----\n"
+ "MIIBDAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz\n"
+ "+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a\n"
+ "87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7\n"
+ "YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi\n"
+ "7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD\n"
+ "ssbzSibBsu/6iGtCOGEoXJf//////////wIBAgICAOE=\n"
+ "-----END DH PARAMETERS-----\n";
+
+static const gnutls_datum_t ffdhe_pkcs3_param = {
+ ffdhe2048,
+ sizeof(ffdhe2048)
+};
+#endif
using namespace rfb;
@@ -50,10 +66,14 @@ StringParameter SSecurityTLS::X509_KeyFile
static LogWriter vlog("TLS");
SSecurityTLS::SSecurityTLS(SConnection* sc, bool _anon)
- : SSecurity(sc), session(NULL), dh_params(NULL), anon_cred(NULL),
+ : SSecurity(sc), session(NULL), anon_cred(NULL),
cert_cred(NULL), anon(_anon), tlsis(NULL), tlsos(NULL),
rawis(NULL), rawos(NULL)
{
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
+ dh_params = NULL;
+#endif
+
certfile = X509_CertFile.getData();
keyfile = X509_KeyFile.getData();
@@ -70,10 +90,12 @@ void SSecurityTLS::shutdown()
}
}
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
if (dh_params) {
gnutls_dh_params_deinit(dh_params);
dh_params = 0;
}
+#endif
if (anon_cred) {
gnutls_anon_free_server_credentials(anon_cred);
@@ -198,17 +220,21 @@ void SSecurityTLS::setParams(gnutls_session_t session)
throw AuthFailureException("gnutls_set_priority_direct failed");
}
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_dh_params_init failed");
- if (gnutls_dh_params_generate2(dh_params, DH_BITS) != GNUTLS_E_SUCCESS)
+ if (gnutls_dh_params_generate2(dh_params, gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM)) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_dh_params_generate2 failed");
- throw AuthFailureException("gnutls_dh_params_generate2 failed");
+ if (gnutls_dh_params_import_pkcs3(dh_params, &ffdhe_pkcs3_param, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS)
+ throw AuthFailureException("gnutls_dh_params_import_pkcs3 failed");
+#endif
if (anon) {
if (gnutls_anon_allocate_server_credentials(&anon_cred) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_anon_allocate_server_credentials failed");
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
gnutls_anon_set_server_dh_params(anon_cred, dh_params);
+#endif
if (gnutls_credentials_set(session, GNUTLS_CRD_ANON, anon_cred)
!= GNUTLS_E_SUCCESS)
@@ -220,7 +246,9 @@ void SSecurityTLS::setParams(gnutls_session_t session)
if (gnutls_certificate_allocate_credentials(&cert_cred) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_certificate_allocate_credentials failed");
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
gnutls_certificate_set_dh_params(cert_cred, dh_params);
+#endif
switch (gnutls_certificate_set_x509_key_file(cert_cred, certfile, keyfile, GNUTLS_X509_FMT_PEM)) {
case GNUTLS_E_SUCCESS:
diff --git a/common/rfb/SSecurityTLS.h b/common/rfb/SSecurityTLS.h
index dd89bb4..0cb463d 100644
--- a/common/rfb/SSecurityTLS.h
+++ b/common/rfb/SSecurityTLS.h
@@ -36,6 +36,13 @@
#include <rdr/OutStream.h>
#include <gnutls/gnutls.h>
+/* In GnuTLS 3.6.0 DH parameter generation was deprecated. RFC7919 is used instead.
+ * GnuTLS before 3.6.0 doesn't know about RFC7919 so we will have to import it.
+ */
+#if GNUTLS_VERSION_NUMBER < 0x030600
+#define SSECURITYTLS__USE_DEPRECATED_DH
+#endif
+
namespace rfb {
class SSecurityTLS : public SSecurity {
@@ -55,7 +62,9 @@ namespace rfb {
private:
gnutls_session_t session;
+#if defined (SSECURITYTLS__USE_DEPRECATED_DH)
gnutls_dh_params_t dh_params;
+#endif
gnutls_anon_server_credentials_t anon_cred;
gnutls_certificate_credentials_t cert_cred;
char *keyfile, *certfile;

View File

@ -5,7 +5,7 @@
Name: tigervnc
Version: 1.11.0
Release: 18%{?dist}
Release: 19%{?dist}
Summary: A TigerVNC remote display system
%global _hardened_build 1
@ -23,26 +23,27 @@ Source4: HOWTO.md
Source5: vncserver
Source6: vncserver.man
Patch4: tigervnc-let-user-know-about-not-using-view-only-password.patch
Patch5: tigervnc-working-tls-on-fips-systems.patch
Patch6: tigervnc-utilize-system-crypto-policies.patch
Patch7: tigervnc-passwd-crash-with-malloc-checks.patch
Patch8: tigervnc-use-gnome-as-default-session.patch
Patch1: tigervnc-use-gnome-as-default-session.patch
# Upstream patches (can be dropped with next Tigervnc release)
Patch51: tigervnc-let-user-know-about-not-using-view-only-password.patch
Patch52: tigervnc-working-tls-on-fips-systems.patch
Patch53: tigervnc-utilize-system-crypto-policies.patch
Patch54: tigervnc-passwd-crash-with-malloc-checks.patch
Patch55: tigervnc-tolerate-specifying-boolparam.patch
Patch56: tigervnc-systemd-service.patch
Patch57: tigervnc-correctly-start-vncsession-as-daemon.patch
Patch58: tigervnc-selinux-missing-compression-and-correct-location.patch
Patch59: tigervnc-selinux-policy-improvements.patch
Patch60: tigervnc-argb-runtime-ximage-byteorder-selection.patch
# Upstream patches
Patch50: tigervnc-tolerate-specifying-boolparam.patch
Patch51: tigervnc-systemd-service.patch
Patch52: tigervnc-correctly-start-vncsession-as-daemon.patch
Patch53: tigervnc-selinux-missing-compression-and-correct-location.patch
Patch54: tigervnc-selinux-policy-improvements.patch
Patch55: tigervnc-argb-runtime-ximage-byteorder-selection.patch
# This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg
Patch100: tigervnc-xserver120.patch
# 1326867 - [RHEL7.3] GLX applications in an Xvnc session fails to start
Patch101: 0001-rpath-hack.patch
BuildRequires: make
BuildRequires: make
BuildRequires: gcc-c++
BuildRequires: libX11-devel, automake, autoconf, libtool, gettext, gettext-autopoint
BuildRequires: libXext-devel, xorg-x11-server-source, libXi-devel
@ -162,25 +163,19 @@ done
%patch101 -p1 -b .rpath
popd
# Bug 1447555 - view-only accepts enter, unclear whether default password is generated or not
%patch4 -p1 -b .let-user-know-about-not-using-view-only-password
# Bug 1492107 - VNC cannot be used when FIPS is enabled because DH_BITS is too low
%patch5 -p1 -b .working-tls-on-fips-systems
# Utilize system-wide crypto policies
%patch6 -p1 -b .utilize-system-crypto-policies.patch
%patch7 -p1 -b .passwd-crash-with-malloc-checks
%patch8 -p1 -b .use-gnome-as-default-session
%patch1 -p1 -b .use-gnome-as-default-session
# Upstream patches
%patch50 -p1 -b .tolerate-specifying-boolparam
%patch51 -p1 -b .systemd-service
%patch52 -p1 -b .correctly-start-vncsession-as-daemon
%patch53 -p1 -b .selinux-missing-compression-and-correct-location
%patch54 -p1 -b .selinux-policy-improvements
%patch55 -p1 -b .argb-runtime-ximage-byteorder-selection
%patch51 -p1 -b .let-user-know-about-not-using-view-only-password
%patch52 -p1 -b .working-tls-on-fips-systems
%patch53 -p1 -b .utilize-system-crypto-policies
%patch54 -p1 -b .passwd-crash-with-malloc-checks
%patch55 -p1 -b .tolerate-specifying-boolparam
%patch56 -p1 -b .systemd-service
%patch57 -p1 -b .correctly-start-vncsession-as-daemon
%patch58 -p1 -b .selinux-missing-compression-and-correct-location
%patch59 -p1 -b .selinux-policy-improvements
%patch60 -p1 -b .argb-runtime-ximage-byteorder-selection
%build
%ifarch sparcv9 sparc64 s390 s390x
@ -360,6 +355,10 @@ fi
%ghost %verify(not md5 size mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
%changelog
* Mon Aug 16 2021 Jan Grulich <jgrulich@redhat.com> - 1.11.0-19
- Sync upstream patches + drop unused patches
Resolves: bz#1985858
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1.11.0-18
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688

View File

@ -892,6 +892,6 @@ sub SanityCheck
sub NotifyAboutDeprecation
{
warn "\nWARNING: vncserver has been replaced by a systemd unit and is about to be removed in the next Fedora release.\n";
warn "\nWARNING: vncserver has been replaced by a systemd unit and is now considered deprecated and removed in upstream.\n";
warn "Please read /usr/share/doc/tigervnc/HOWTO.md for more information.\n";
}