Add option "ApproveLoggedUserOnly" allowing to connect only the user
owning the running session Resolves: RHEL-34880
This commit is contained in:
parent
b3a7f8a95f
commit
8ed86c60ec
@ -0,0 +1,219 @@
|
||||
From 8ac9bf0c061666d89d345a3d7149e1ef9c771655 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/xserver/hw/vnc/XserverDesktop.cc | 120 +++++++++++++++++++++++++-
|
||||
unix/xserver/hw/vnc/XserverDesktop.h | 7 ++
|
||||
3 files changed, 126 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx
|
||||
index 3831812..736a563 100644
|
||||
--- a/common/rfb/VNCServerST.cxx
|
||||
+++ b/common/rfb/VNCServerST.cxx
|
||||
@@ -696,13 +696,6 @@ void VNCServerST::queryConnection(VNCSConnectionST* client,
|
||||
return;
|
||||
}
|
||||
|
||||
- // - Are we configured to do queries?
|
||||
- if (!rfb::Server::queryConnect &&
|
||||
- !client->getSock()->requiresQuery()) {
|
||||
- approveConnection(client->getSock(), true, NULL);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
// - Does the client have the right to bypass the query?
|
||||
if (client->accessCheck(AccessNoQuery))
|
||||
{
|
||||
diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc
|
||||
index d4ee16b..dce1f6c 100644
|
||||
--- a/unix/xserver/hw/vnc/XserverDesktop.cc
|
||||
+++ b/unix/xserver/hw/vnc/XserverDesktop.cc
|
||||
@@ -52,6 +52,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,7 +76,14 @@ IntParameter queryConnectTimeout("QueryConnectTimeout",
|
||||
"Accept Connection dialog before "
|
||||
"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.",
|
||||
+ false);
|
||||
+#endif
|
||||
|
||||
XserverDesktop::XserverDesktop(int screenIndex_,
|
||||
std::list<network::SocketListener*> listeners_,
|
||||
@@ -168,11 +180,117 @@ 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;
|
||||
+
|
||||
+ 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);
|
||||
+ if (strcmp(display, serverDisplay.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_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 e604295..aed188e 100644
|
||||
--- a/unix/xserver/hw/vnc/XserverDesktop.h
|
||||
+++ b/unix/xserver/hw/vnc/XserverDesktop.h
|
||||
@@ -108,6 +108,13 @@ public:
|
||||
virtual void grabRegion(const rfb::Region& r);
|
||||
|
||||
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 b9c429f..17df086 100644
|
||||
--- a/unix/xserver/hw/vnc/Xvnc.man
|
||||
+++ b/unix/xserver/hw/vnc/Xvnc.man
|
||||
@@ -204,6 +204,12 @@ to allow any user to authenticate using this security type. Specify \fB%u\fP
|
||||
to allow the user of the server process. Default is to deny all users.
|
||||
.
|
||||
.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.
|
||||
+.
|
||||
+.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.
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
Name: tigervnc
|
||||
Version: 1.14.0
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
Summary: A TigerVNC remote display system
|
||||
|
||||
%global _hardened_build 1
|
||||
@ -23,7 +23,10 @@ Source5: vncserver
|
||||
|
||||
# Downstream patches
|
||||
Patch1: tigervnc-use-gnome-as-default-session.patch
|
||||
# https://github.com/TigerVNC/tigervnc/pull/1425
|
||||
Patch2: tigervnc-vncsession-restore-script-systemd-service.patch
|
||||
# https://github.com/TigerVNC/tigervnc/pull/1792
|
||||
Patch3: tigervnc-add-option-allowing-to-connect-only-user-owning-session.patch
|
||||
|
||||
# Upstream patches
|
||||
Patch50: tigervnc-vncsession-use-bin-sh-when-shell-not-set.patch
|
||||
@ -91,7 +94,13 @@ BuildRequires: xorg-x11-util-macros
|
||||
BuildRequires: xorg-x11-xtrans-devel
|
||||
|
||||
# SELinux
|
||||
BuildRequires: libselinux-devel, selinux-policy-devel, systemd
|
||||
BuildRequires: libselinux-devel
|
||||
BuildRequires: selinux-policy-devel
|
||||
|
||||
# For RHEL-34880
|
||||
BuildRequires: pkgconfig(dbus-1) >= 1.0
|
||||
BuildRequires: pkgconfig(libsystemd) >= 209
|
||||
BuildRequires: pkgconfig(libudev) >= 143
|
||||
|
||||
Requires(post): coreutils
|
||||
Requires(postun):coreutils
|
||||
@ -199,6 +208,7 @@ popd
|
||||
# Tigervnc patches
|
||||
%patch -P1 -p1 -b .use-gnome-as-default-session
|
||||
%patch -P2 -p1 -b .vncsession-restore-script-systemd-service
|
||||
%patch -P3 -p1 -b .add-option-allowing-to-connect-only-user-owning-session
|
||||
|
||||
# Upstream patches
|
||||
%patch -P50 -p1 -b .vncsession-use-bin-sh-when-shell-not-set
|
||||
@ -247,7 +257,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
|
||||
@ -390,11 +402,16 @@ fi
|
||||
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
|
||||
|
||||
%changelog
|
||||
* Fri Sep 27 2024 Jan Grulich <jgrulich@redhat.com> - 1.14.0-4
|
||||
- Add option "ApproveLoggedUserOnly" allowing to connect only the user
|
||||
owning the running session
|
||||
Resolves: RHEL-34880
|
||||
|
||||
* Wed Sep 04 2024 Jan Grulich <jgrulich@redhat.com> - 1.14.0-3
|
||||
- Move old log to log.old if present (fix patch)
|
||||
Resolves: RHEL-54294
|
||||
|
||||
* Tue Aug 23 2024 Jan Grulich <jgrulich@redhat.com> - 1.14.0-2
|
||||
* Tue Aug 20 2024 Jan Grulich <jgrulich@redhat.com> - 1.14.0-2
|
||||
- 1.14.0
|
||||
Resolves: RHEL-45316
|
||||
- Move old log to log.old if present
|
||||
|
||||
Loading…
Reference in New Issue
Block a user