Dynamically apply permissions
This commit is contained in:
@@ -59,7 +59,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
|||||||
losslessTimer(this), kbdLogTimer(this), server(server_), updates(false),
|
losslessTimer(this), kbdLogTimer(this), server(server_), updates(false),
|
||||||
updateRenderedCursor(false), removeRenderedCursor(false),
|
updateRenderedCursor(false), removeRenderedCursor(false),
|
||||||
continuousUpdates(false), encodeManager(this, &server_->encCache),
|
continuousUpdates(false), encodeManager(this, &server_->encCache),
|
||||||
pointerEventTime(0),
|
needsPermCheck(false), pointerEventTime(0),
|
||||||
clientHasCursor(false),
|
clientHasCursor(false),
|
||||||
accessRights(AccessDefault), startTime(time(0))
|
accessRights(AccessDefault), startTime(time(0))
|
||||||
{
|
{
|
||||||
@@ -1126,6 +1126,22 @@ void VNCSConnectionST::writeFramebufferUpdate()
|
|||||||
if (isCongested())
|
if (isCongested())
|
||||||
return;
|
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
|
// Updates often consists of many small writes, and in continuous
|
||||||
// mode, we will also have small fence messages around the update. We
|
// 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
|
// 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.
|
// or because the current cursor position has not been set by this client.
|
||||||
bool needRenderedCursor();
|
bool needRenderedCursor();
|
||||||
|
|
||||||
|
void recheckPerms() {
|
||||||
|
needsPermCheck = true;
|
||||||
|
}
|
||||||
|
|
||||||
network::Socket* getSock() { return sock; }
|
network::Socket* getSock() { return sock; }
|
||||||
void add_changed(const Region& region) { updates.add_changed(region); }
|
void add_changed(const Region& region) { updates.add_changed(region); }
|
||||||
void add_changed_all() { updates.add_changed(server->pb->getRect()); }
|
void add_changed_all() { updates.add_changed(server->pb->getRect()); }
|
||||||
@@ -190,6 +194,7 @@ namespace rfb {
|
|||||||
bool write, owner;
|
bool write, owner;
|
||||||
if (!getPerms(write, owner) || !write)
|
if (!getPerms(write, owner) || !write)
|
||||||
accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents));
|
accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents));
|
||||||
|
needsPermCheck = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timer callbacks
|
// Timer callbacks
|
||||||
@@ -259,6 +264,7 @@ namespace rfb {
|
|||||||
|
|
||||||
char user[32];
|
char user[32];
|
||||||
char kasmpasswdpath[4096];
|
char kasmpasswdpath[4096];
|
||||||
|
bool needsPermCheck;
|
||||||
|
|
||||||
time_t lastEventTime;
|
time_t lastEventTime;
|
||||||
time_t pointerEventTime;
|
time_t pointerEventTime;
|
||||||
|
|||||||
@@ -63,6 +63,11 @@
|
|||||||
|
|
||||||
#include <rdr/types.h>
|
#include <rdr/types.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/inotify.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wordexp.h>
|
||||||
|
|
||||||
using namespace rfb;
|
using namespace rfb;
|
||||||
|
|
||||||
static LogWriter slog("VNCServerST");
|
static LogWriter slog("VNCServerST");
|
||||||
@@ -73,6 +78,9 @@ EncCache VNCServerST::encCache;
|
|||||||
// -=- VNCServerST Implementation
|
// -=- VNCServerST Implementation
|
||||||
//
|
//
|
||||||
|
|
||||||
|
static char kasmpasswdpath[4096];
|
||||||
|
extern rfb::StringParameter basicauth;
|
||||||
|
|
||||||
// -=- Constructors/Destructor
|
// -=- Constructors/Destructor
|
||||||
|
|
||||||
VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
||||||
@@ -87,6 +95,26 @@ VNCServerST::VNCServerST(const char* name_, SDesktop* desktop_)
|
|||||||
{
|
{
|
||||||
lastUserInputTime = lastDisconnectTime = time(0);
|
lastUserInputTime = lastDisconnectTime = time(0);
|
||||||
slog.debug("creating single-threaded server %s", name.buf);
|
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()
|
VNCServerST::~VNCServerST()
|
||||||
@@ -659,8 +687,34 @@ void VNCServerST::writeUpdate()
|
|||||||
encCache.clear();
|
encCache.clear();
|
||||||
encCache.enabled = clients.size() > 1;
|
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) {
|
for (ci = clients.begin(); ci != clients.end(); ci = ci_next) {
|
||||||
ci_next = ci; ci_next++;
|
ci_next = ci; ci_next++;
|
||||||
|
|
||||||
|
if (permcheck)
|
||||||
|
(*ci)->recheckPerms();
|
||||||
|
|
||||||
(*ci)->add_copied(ui.copied, ui.copy_delta);
|
(*ci)->add_copied(ui.copied, ui.copy_delta);
|
||||||
(*ci)->add_copypassed(ui.copypassed);
|
(*ci)->add_copypassed(ui.copypassed);
|
||||||
(*ci)->add_changed(ui.changed);
|
(*ci)->add_changed(ui.changed);
|
||||||
|
|||||||
@@ -249,6 +249,8 @@ namespace rfb {
|
|||||||
bool disableclients;
|
bool disableclients;
|
||||||
|
|
||||||
Timer frameTimer;
|
Timer frameTimer;
|
||||||
|
|
||||||
|
int inotifyfd;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user