Import from CS git
This commit is contained in:
parent
892a31ab5a
commit
319fdcb0c6
@ -0,0 +1,265 @@
|
||||
From 69b0fd6d77ea5968bd815188ee2bda3d282ebc60 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Grulich <jgrulich@redhat.com>
|
||||
Date: Mon, 29 Jul 2024 14:31:14 +0200
|
||||
Subject: [PATCH] Add option allowing to connect only the user owning the
|
||||
running session
|
||||
|
||||
Checks, whether the user who is trying to authenticate is already logged
|
||||
into the running session in order to allow or reject the connection.
|
||||
This is expected to be used with 'plain' security type in combination
|
||||
with 'PlainUsers=*' option allowing everyone to connect to the session.
|
||||
---
|
||||
common/rfb/VNCServerST.cxx | 7 --
|
||||
unix/x0vncserver/XDesktop.cxx | 8 ++
|
||||
unix/xserver/hw/vnc/XserverDesktop.cc | 137 ++++++++++++++++++++++++++
|
||||
unix/xserver/hw/vnc/XserverDesktop.h | 7 ++
|
||||
unix/xserver/hw/vnc/Xvnc.man | 7 ++
|
||||
5 files changed, 159 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
|
||||
index b99d33b..aa8d53e 100644
|
||||
--- a/common/rfb/VNCServerST.cxx
|
||||
+++ b/common/rfb/VNCServerST.cxx
|
||||
@@ -682,13 +682,6 @@ void VNCServerST::queryConnection(VNCSConnectionST* client,
|
||||
return;
|
||||
}
|
||||
|
||||
- // - Are we configured to do queries?
|
||||
- if (!rfb::Server::queryConnect &&
|
||||
- !client->getSock()->requiresQuery()) {
|
||||
- approveConnection(client->getSock(), true, nullptr);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
// - Does the client have the right to bypass the query?
|
||||
if (client->accessCheck(AccessNoQuery))
|
||||
{
|
||||
diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx
|
||||
index b43e3f7..3d00e23 100644
|
||||
--- a/unix/x0vncserver/XDesktop.cxx
|
||||
+++ b/unix/x0vncserver/XDesktop.cxx
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <network/Socket.h>
|
||||
|
||||
#include <rfb/LogWriter.h>
|
||||
+#include <rfb/ServerCore.h>
|
||||
|
||||
#include <x0vncserver/XDesktop.h>
|
||||
|
||||
@@ -320,6 +321,13 @@ void XDesktop::queryConnection(network::Socket* sock,
|
||||
{
|
||||
assert(isRunning());
|
||||
|
||||
+ // - Are we configured to do queries?
|
||||
+ if (!rfb::Server::queryConnect &&
|
||||
+ !sock->requiresQuery()) {
|
||||
+ server->approveConnection(sock, true, nullptr);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// Someone already querying?
|
||||
if (queryConnectSock) {
|
||||
std::list<network::Socket*> sockets;
|
||||
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
|
||||
index 260ed3a..c8741f6 100644
|
||||
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
|
||||
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
|
||||
@@ -51,6 +51,11 @@
|
||||
#include "XorgGlue.h"
|
||||
#include "vncInput.h"
|
||||
|
||||
+#if HAVE_SYSTEMD_DAEMON
|
||||
+# include <pwd.h>
|
||||
+# include <systemd/sd-login.h>
|
||||
+#endif
|
||||
+
|
||||
extern "C" {
|
||||
void vncSetGlueContext(int screenIndex);
|
||||
void vncPresentMscEvent(uint64_t id, uint64_t msc);
|
||||
@@ -71,6 +76,15 @@ IntParameter queryConnectTimeout("QueryConnectTimeout",
|
||||
"rejecting the connection",
|
||||
10);
|
||||
|
||||
+#ifdef HAVE_SYSTEMD_DAEMON
|
||||
+BoolParameter approveLoggedUserOnly
|
||||
+("ApproveLoggedUserOnly",
|
||||
+ "Approve only the user who is currently logged into the session."
|
||||
+ "This is expected to be combined with 'plain' security type and with "
|
||||
+ "'PlainUsers=*' option allowing everyone to connect to the session."
|
||||
+ "Default is off.",
|
||||
+ false);
|
||||
+#endif
|
||||
|
||||
XserverDesktop::XserverDesktop(int screenIndex_,
|
||||
std::list<network::SocketListener*> listeners_,
|
||||
@@ -164,11 +178,134 @@ void XserverDesktop::init(rfb::VNCServer* vs)
|
||||
// ready state
|
||||
}
|
||||
|
||||
+#ifdef HAVE_SYSTEMD_DAEMON
|
||||
+bool XserverDesktop::checkUserLogged(const char* userName)
|
||||
+{
|
||||
+ bool ret = false;
|
||||
+ bool noUserSession = true;
|
||||
+ int res;
|
||||
+ char **sessions;
|
||||
+
|
||||
+ res = sd_get_sessions(&sessions);
|
||||
+ if (res < 0) {
|
||||
+ vlog.debug("logind: failed to get sessions");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (sessions != nullptr && sessions[0] != nullptr) {
|
||||
+ for (int i = 0; sessions[i]; i++) {
|
||||
+ uid_t uid;
|
||||
+ char *clazz;
|
||||
+ char *display;
|
||||
+ char *type;
|
||||
+ char *state;
|
||||
+
|
||||
+ res = sd_session_get_type(sessions[i], &type);
|
||||
+ if (res < 0) {
|
||||
+ vlog.debug("logind: failed to determine session type");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp(type, "x11") != 0) {
|
||||
+ free(type);
|
||||
+ continue;
|
||||
+ }
|
||||
+ free(type);
|
||||
+
|
||||
+ res = sd_session_get_display(sessions[i], &display);
|
||||
+ if (res < 0) {
|
||||
+ vlog.debug("logind: failed to determine display of session");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ std::string serverDisplay = ":" + std::to_string(screenIndex);
|
||||
+ std::string serverDisplayIPv4 = "127.0.0.1:" + std::to_string(screenIndex);
|
||||
+ std::string serverDisplayIPv6 = "::1:" + std::to_string(screenIndex);
|
||||
+ if ((strcmp(display, serverDisplay.c_str()) != 0) &&
|
||||
+ (strcmp(display, serverDisplayIPv4.c_str()) != 0) &&
|
||||
+ (strcmp(display, serverDisplayIPv6.c_str()) != 0)) {
|
||||
+ free(display);
|
||||
+ continue;
|
||||
+ }
|
||||
+ free(display);
|
||||
+
|
||||
+ res = sd_session_get_class(sessions[i], &clazz);
|
||||
+ if (res < 0) {
|
||||
+ vlog.debug("logind: failed to determine session class");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ res = sd_session_get_state(sessions[i], &state);
|
||||
+ if (res < 0) {
|
||||
+ vlog.debug("logind: failed to determine session state");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp(state, "closing") == 0) {
|
||||
+ free(state);
|
||||
+ continue;
|
||||
+ }
|
||||
+ free(state);
|
||||
+
|
||||
+ res = sd_session_get_uid(sessions[i], &uid);
|
||||
+ if (res < 0) {
|
||||
+ vlog.debug("logind: failed to determine user id of session");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (uid != 0 && strcmp(clazz, "user") == 0) {
|
||||
+ noUserSession = false;
|
||||
+ }
|
||||
+ free(clazz);
|
||||
+
|
||||
+ struct passwd *pw = getpwnam(userName);
|
||||
+ if (!pw) {
|
||||
+ vlog.debug("logind: user not found");
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (uid == pw->pw_uid) {
|
||||
+ ret = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (sessions) {
|
||||
+ for (int i = 0; sessions[i]; i ++) {
|
||||
+ free(sessions[i]);
|
||||
+ }
|
||||
+
|
||||
+ free (sessions);
|
||||
+ }
|
||||
+
|
||||
+ // If we didn't find a matching user, we can still allow the user
|
||||
+ // to log in if there is no user session yet.
|
||||
+ return !ret ? noUserSession : ret;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
void XserverDesktop::queryConnection(network::Socket* sock,
|
||||
const char* userName)
|
||||
{
|
||||
int count;
|
||||
|
||||
+#ifdef HAVE_SYSTEMD_DAEMON
|
||||
+ // - Only owner of the session can be approved
|
||||
+ if (approveLoggedUserOnly && !checkUserLogged(userName)) {
|
||||
+ server->approveConnection(sock, false,
|
||||
+ "The user is not owner of the running session");
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ // - Are we configured to do queries?
|
||||
+ if (!rfb::Server::queryConnect &&
|
||||
+ !sock->requiresQuery()) {
|
||||
+ server->approveConnection(sock, true, nullptr);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (queryConnectTimer.isStarted()) {
|
||||
server->approveConnection(sock, false, "Another connection is currently being queried.");
|
||||
return;
|
||||
diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h
|
||||
index 8c543db..8d6bde4 100644
|
||||
--- a/unix/xserver/hw/vnc/XserverDesktop.h
|
||||
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
|
||||
@@ -108,6 +108,13 @@ public:
|
||||
void grabRegion(const rfb::Region& r) override;
|
||||
|
||||
protected:
|
||||
+#ifdef HAVE_SYSTEMD_DAEMON
|
||||
+ // - Check whether user is logged into a session
|
||||
+ // Returns true if user is already logged or there is no
|
||||
+ // user session at all.
|
||||
+ bool checkUserLogged(const char* userName);
|
||||
+#endif
|
||||
+
|
||||
bool handleListenerEvent(int fd,
|
||||
std::list<network::SocketListener*>* sockets,
|
||||
rfb::VNCServer* sockserv);
|
||||
diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man
|
||||
index d6b1664..24384df 100644
|
||||
--- a/unix/xserver/hw/vnc/Xvnc.man
|
||||
+++ b/unix/xserver/hw/vnc/Xvnc.man
|
||||
@@ -200,6 +200,13 @@ Never treat incoming connections as shared, regardless of the client-specified
|
||||
setting. Default is off.
|
||||
.
|
||||
.TP
|
||||
+.B \-ApproveLoggedUserOnly
|
||||
+Approve only the user who is currently logged into the session.
|
||||
+This is expected to be combined with "Plain" security type and with
|
||||
+"PlainUsers=*" option allowing everyone to connect to the session.
|
||||
+Default is off.
|
||||
+.
|
||||
+.TP
|
||||
.B \-pam_service \fIname\fP, \-PAMService \fIname\fP
|
||||
PAM service name to use when authentication users using any of the "Plain"
|
||||
security types. Default is \fBvnc\fP.
|
@ -0,0 +1,14 @@
|
||||
diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx
|
||||
index 466aa1a2..197d60dc 100644
|
||||
--- a/unix/vncpasswd/vncpasswd.cxx
|
||||
+++ b/unix/vncpasswd/vncpasswd.cxx
|
||||
@@ -147,8 +147,7 @@ static std::vector<uint8_t> readpassword() {
|
||||
}
|
||||
|
||||
if (first.size() > 8) {
|
||||
- fprintf(stderr,"Password should not be greater than 8 characters\nBecause only 8 valid characters are used - try again\n");
|
||||
- continue;
|
||||
+ fprintf(stderr,"Password should not be greater than 8 characters\nBecause only 8 valid characters are used\n");
|
||||
}
|
||||
|
||||
#ifdef HAVE_PWQUALITY
|
@ -0,0 +1,47 @@
|
||||
From 1f1aaca09a1f9919f5169caea9c396b14c2af765 Mon Sep 17 00:00:00 2001
|
||||
From: Pierre Ossman <ossman@cendio.se>
|
||||
Date: Tue, 8 Apr 2025 14:41:04 +0200
|
||||
Subject: [PATCH] Don't print Xvnc banner before parsing args
|
||||
|
||||
If we'll be running in inetd mode, then stdout and stderr will be a
|
||||
client socket and not an appropriate place for logging.
|
||||
|
||||
Mimic what Xorg does instead.
|
||||
---
|
||||
unix/xserver/hw/vnc/xvnc.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c
|
||||
index ddb249937..a13168c47 100644
|
||||
--- a/unix/xserver/hw/vnc/xvnc.c
|
||||
+++ b/unix/xserver/hw/vnc/xvnc.c
|
||||
@@ -446,7 +446,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
|
||||
}
|
||||
|
||||
if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) {
|
||||
- /* Already shown at start */
|
||||
+ vncPrintBanner();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@@ -1171,8 +1171,11 @@ InitOutput(ScreenInfo * scrInfo, int argc, char **argv)
|
||||
int i;
|
||||
int NumFormats = 0;
|
||||
|
||||
- if (serverGeneration == 1)
|
||||
+ if (serverGeneration == 1) {
|
||||
+ vncPrintBanner();
|
||||
+
|
||||
LoadExtensionList(vncExtensions, ARRAY_SIZE(vncExtensions), TRUE);
|
||||
+ }
|
||||
|
||||
#if XORG_AT_LEAST(1, 20, 0)
|
||||
xorgGlxCreateVendor();
|
||||
@@ -1266,7 +1269,5 @@ vncClientGone(int fd)
|
||||
int
|
||||
main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
- vncPrintBanner();
|
||||
-
|
||||
return dix_main(argc, argv, envp);
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
Name: tigervnc
|
||||
Version: 1.15.0
|
||||
Release: 1%{?dist}
|
||||
Release: 5%{?dist}
|
||||
Summary: A TigerVNC remote display system
|
||||
|
||||
%global _hardened_build 1
|
||||
@ -26,10 +26,15 @@ Patch1: tigervnc-use-gnome-as-default-session.patch
|
||||
# https://github.com/TigerVNC/tigervnc/pull/1425
|
||||
Patch2: tigervnc-vncsession-restore-script-systemd-service.patch
|
||||
Patch3: tigervnc-dont-install-appstream-metadata-file.patch
|
||||
# Only warn about passwords longer than 8 characters, but allow them to be used as in the past
|
||||
Patch4: tigervnc-allow-use-of-passwords-longer-than-eight-characters.patch
|
||||
# https://github.com/TigerVNC/tigervnc/pull/1792
|
||||
Patch5: tigervnc-add-option-allowing-to-connect-only-user-owning-session.patch
|
||||
|
||||
# Upstream patches
|
||||
Patch50: tigervnc-add-selinux-policy-rules-allowing-create-dirs-under-root-dir.patch
|
||||
Patch51: tigervnc-add-selinux-policy-rules-allowing-access-to-proc-sys-fs-nr-open.patch
|
||||
Patch52: tigervnc-dont-print-xvnc-banner-before-parsing-args.patch
|
||||
|
||||
# Upstreamable patches
|
||||
|
||||
@ -102,6 +107,11 @@ BuildRequires: xorg-x11-xtrans-devel
|
||||
BuildRequires: libselinux-devel
|
||||
BuildRequires: selinux-policy-devel
|
||||
|
||||
# For RHEL-91104
|
||||
BuildRequires: pkgconfig(dbus-1) >= 1.0
|
||||
BuildRequires: pkgconfig(libsystemd) >= 209
|
||||
BuildRequires: pkgconfig(libudev) >= 143
|
||||
|
||||
Requires(post): coreutils
|
||||
Requires(postun):coreutils
|
||||
|
||||
@ -225,10 +235,13 @@ popd
|
||||
%patch -P1 -p1 -b .use-gnome-as-default-session
|
||||
%patch -P2 -p1 -b .vncsession-restore-script-systemd-service
|
||||
%patch -P3 -p1 -b .dont-install-appstream-metadata-file.patch
|
||||
%patch -P4 -p1 -b .allow-use-of-passwords-longer-than-eight-characters
|
||||
%patch -P5 -p1 -b .add-option-allowing-to-connect-only-user-owning-session
|
||||
|
||||
# Upstream patches
|
||||
%patch -P50 -p1 -b .add-selinux-policy-rules-allowing-create-dirs-under-root-dir
|
||||
%patch -P51 -p1 -b .add-selinux-policy-rules-allowing-access-to-proc-sys-fs-nr-open
|
||||
%patch -P52 -p1 -b .dont-print-xvnc-banner-before-parsing-args
|
||||
|
||||
# Upstreamable patches
|
||||
|
||||
@ -257,7 +270,9 @@ autoreconf -fiv
|
||||
--disable-config-udev \
|
||||
--without-dtrace \
|
||||
--disable-devel-docs \
|
||||
--disable-selective-werror
|
||||
--disable-selective-werror \
|
||||
--enable-systemd-logind \
|
||||
--enable-config-udev
|
||||
|
||||
make %{?_smp_mflags}
|
||||
popd
|
||||
@ -382,6 +397,23 @@ fi
|
||||
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
|
||||
|
||||
%changelog
|
||||
* Tue May 27 2025 Jan Grulich <jgrulich@redhat.com> - 1.15.0-5
|
||||
- Fix broken authentication with x0vncserver
|
||||
Resolves: RHEL-93729
|
||||
|
||||
* Thu May 15 2025 Jan Grulich <jgrulich@redhat.com> - 1.15.0-4
|
||||
- Add option "ApproveLoggedUserOnly" allowing to connect only the user
|
||||
owning the running session
|
||||
Resolves: RHEL-91104
|
||||
|
||||
* Wed Apr 30 2025 Jan Grulich <jgrulich@redhat.com> - 1.15.0-3
|
||||
- Only warn about 8 characters limit, but let it proceed
|
||||
Resolves: RHEL-89430
|
||||
|
||||
* Wed Apr 16 2025 Jan Grulich <jgrulich@redhat.com> - 1.15.0-2
|
||||
- Fix inetd mode not working
|
||||
Resolves: RHEL-86513
|
||||
|
||||
* Wed Feb 26 2025 Jan Grulich <jgrulich@redhat.com> - 1.15.0-1
|
||||
- 1.15.0
|
||||
Resolves: RHEL-79161
|
||||
|
Loading…
Reference in New Issue
Block a user