Dynamically apply permissions

This commit is contained in:
Lauri Kasanen 2020-10-13 13:38:18 +03:00
parent 263d05a296
commit 0c83a86bc8
4 changed files with 79 additions and 1 deletions

View File

@ -59,7 +59,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
losslessTimer(this), kbdLogTimer(this), server(server_), updates(false),
updateRenderedCursor(false), removeRenderedCursor(false),
continuousUpdates(false), encodeManager(this, &server_->encCache),
pointerEventTime(0),
needsPermCheck(false), pointerEventTime(0),
clientHasCursor(false),
accessRights(AccessDefault), startTime(time(0))
{
@ -1126,6 +1126,22 @@ void VNCSConnectionST::writeFramebufferUpdate()
if (isCongested())
return;
// Check for permission changes?
if (needsPermCheck) {
needsPermCheck = false;
bool write, owner, ret;
ret = getPerms(write, owner);
if (!ret) {
close("User was deleted");
return;
} else if (!write) {
accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents));
} else {
accessRights |= AccessPtrEvents | AccessKeyEvents;
}
}
// Updates often consists of many small writes, and in continuous
// mode, we will also have small fence messages around the update. We
// need to aggregate these in order to not clog up TCP's congestion

View File

@ -102,6 +102,10 @@ namespace rfb {
// or because the current cursor position has not been set by this client.
bool needRenderedCursor();
void recheckPerms() {
needsPermCheck = true;
}
network::Socket* getSock() { return sock; }
void add_changed(const Region& region) { updates.add_changed(region); }
void add_changed_all() { updates.add_changed(server->pb->getRect()); }
@ -190,6 +194,7 @@ namespace rfb {
bool write, owner;
if (!getPerms(write, owner) || !write)
accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents));
needsPermCheck = false;
}
// Timer callbacks
@ -259,6 +264,7 @@ namespace rfb {
char user[32];
char kasmpasswdpath[4096];
bool needsPermCheck;
time_t lastEventTime;
time_t pointerEventTime;

View File

@ -63,6 +63,11 @@
#include <rdr/types.h>
#include <fcntl.h>
#include <sys/inotify.h>
#include <unistd.h>
#include <wordexp.h>
using namespace rfb;
static LogWriter slog("VNCServerST");
@ -73,6 +78,9 @@ EncCache VNCServerST::encCache;
// -=- VNCServerST Implementation
//
static char kasmpasswdpath[4096];
extern rfb::StringParameter basicauth;
// -=- Constructors/Destructor
VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
@ -87,6 +95,26 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
{
lastUserInputTime = lastDisconnectTime = time(0);
slog.debug("creating single-threaded server %s", name.buf);
kasmpasswdpath[0] = '\0';
wordexp_t wexp;
if (!wordexp(rfb::Server::kasmPasswordFile, &wexp, WRDE_NOCMD))
strncpy(kasmpasswdpath, wexp.we_wordv[0], 4096);
kasmpasswdpath[4095] = '\0';
wordfree(&wexp);
if (kasmpasswdpath[0] && access(kasmpasswdpath, R_OK) == 0) {
// Set up a watch on the password file
inotifyfd = inotify_init();
if (inotifyfd < 0)
slog.error("Failed to init inotify");
int flags = fcntl(inotifyfd, F_GETFL, 0);
fcntl(inotifyfd, F_SETFL, flags | O_NONBLOCK);
if (inotify_add_watch(inotifyfd, kasmpasswdpath, IN_CLOSE_WRITE | IN_DELETE_SELF) < 0)
slog.error("Failed to set watch");
}
}
VNCServerST::~VNCServerST()
@ -659,8 +687,34 @@ void VNCServerST::writeUpdate()
encCache.clear();
encCache.enabled = clients.size() > 1;
// Check if the password file was updated
bool permcheck = false;
if (inotifyfd >= 0) {
char buf[256];
int ret = read(inotifyfd, buf, 256);
int pos = 0;
while (ret > 0) {
const struct inotify_event * const ev = (struct inotify_event *) &buf[pos];
if (ev->mask & IN_IGNORED) {
// file was deleted, set new watch
if (inotify_add_watch(inotifyfd, kasmpasswdpath, IN_CLOSE_WRITE | IN_DELETE_SELF) < 0)
slog.error("Failed to set watch");
}
permcheck = true;
ret -= sizeof(struct inotify_event) - ev->len;
pos += sizeof(struct inotify_event) - ev->len;
}
}
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
ci_next = ci; ci_next++;
if (permcheck)
(*ci)->recheckPerms();
(*ci)->add_copied(ui.copied, ui.copy_delta);
(*ci)->add_copypassed(ui.copypassed);
(*ci)->add_changed(ui.changed);

View File

@ -249,6 +249,8 @@ namespace rfb {
bool disableclients;
Timer frameTimer;
int inotifyfd;
};
};