mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-12-23 23:29:05 +01:00
Dynamically apply permissions
This commit is contained in:
parent
263d05a296
commit
0c83a86bc8
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -249,6 +249,8 @@ namespace rfb {
|
||||
bool disableclients;
|
||||
|
||||
Timer frameTimer;
|
||||
|
||||
int inotifyfd;
|
||||
};
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user