From 1e4ca3563c648f790f477a573fcdc882960a7b37 Mon Sep 17 00:00:00 2001 From: mattmcclaskey Date: Tue, 6 Sep 2022 17:48:44 +0000 Subject: [PATCH] KASM-3119 send full frame on permission changes --- .gitmodules | 2 +- builder/build.sh | 2 +- common/network/websocket.c | 25 +++++++++++++++++++------ common/rfb/VNCSConnectionST.cxx | 2 +- common/rfb/VNCServerST.cxx | 10 ++++++++++ common/rfb/VNCServerST.h | 3 ++- unix/xserver/hw/vnc/XserverDesktop.cc | 9 +++++++++ unix/xserver/hw/vnc/vncExtInit.cc | 9 +++++++++ 8 files changed, 52 insertions(+), 10 deletions(-) diff --git a/.gitmodules b/.gitmodules index e43a13a..2eb9c47 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "kasmweb"] path = kasmweb url = https://github.com/kasmtech/noVNC.git - branch = master + branch = release/0.9.3 diff --git a/builder/build.sh b/builder/build.sh index 095a7a1..63b4600 100755 --- a/builder/build.sh +++ b/builder/build.sh @@ -23,7 +23,7 @@ cd /tmp # default to the version of x in Ubuntu 18.04, otherwise caller will need to specify XORG_VER=${XORG_VER:-"1.19.6"} XORG_PATCH=$(echo "$XORG_VER" | grep -Po '^\d.\d+' | sed 's#\.##') -wget https://www.x.org/archive/individual/xserver/xorg-server-${XORG_VER}.tar.bz2 +wget --no-check-certificate https://www.x.org/archive/individual/xserver/xorg-server-${XORG_VER}.tar.bz2 #git clone https://kasmweb@bitbucket.org/kasmtech/kasmvnc.git #cd kasmvnc diff --git a/common/network/websocket.c b/common/network/websocket.c index 4005d95..eab46cb 100644 --- a/common/network/websocket.c +++ b/common/network/websocket.c @@ -45,6 +45,7 @@ int ssl_initialized = 0; int pipe_error = 0; settings_t settings; +extern int wakeuppipe[2]; void traffic(const char * token) { /*if ((settings.verbose) && (! settings.daemon)) { @@ -1083,6 +1084,9 @@ static uint8_t ownerapi_post(ws_ctx_t *ws_ctx, const char *in, const char * cons free(set->entries); free(set); + //force full frame to all users with at least read + write(wakeuppipe[1], "", 1); + sprintf(buf, "HTTP/1.1 200 OK\r\n" "Server: KasmVNC/4.0\r\n" "Connection: close\r\n" @@ -1172,6 +1176,9 @@ static uint8_t ownerapi_post(ws_ctx_t *ws_ctx, const char *in, const char * cons } } + //force full frame to all users with at least read + write(wakeuppipe[1], "", 1); + free(set->entries); free(set); @@ -1312,7 +1319,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in, const char * const use } } else entry("/api/create_user") { char decname[1024] = "", decpw[1024] = ""; - uint8_t read = 0, write = 0, owner = 0; + uint8_t read_p = 0, write_p = 0, owner_p = 0; param = parse_get(args, "name", &len); if (len) { @@ -1337,29 +1344,32 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in, const char * const use param = parse_get(args, "read", &len); if (len && isalpha(param[0])) { if (!strncmp(param, "true", len)) - read = 1; + read_p = 1; } param = parse_get(args, "write", &len); if (len && isalpha(param[0])) { if (!strncmp(param, "true", len)) - write = 1; + write_p = 1; } param = parse_get(args, "owner", &len); if (len && isalpha(param[0])) { if (!strncmp(param, "true", len)) - owner = 1; + owner_p = 1; } if (!decname[0] || !decpw[0]) goto nope; - if (!settings.adduserCb(settings.messager, decname, decpw, read, write, owner)) { + if (!settings.adduserCb(settings.messager, decname, decpw, read_p, write_p, owner_p)) { handler_msg("Invalid params to create_user\n"); goto nope; } + //force full frame to all users with at least read + write(wakeuppipe[1], "", 1); + sprintf(buf, "HTTP/1.1 200 OK\r\n" "Server: KasmVNC/4.0\r\n" "Connection: close\r\n" @@ -1413,7 +1423,7 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in, const char * const use if (!decname[0]) goto nope; - uint64_t mask = 0; + uint64_t mask = 0; uint8_t myread = 0; param = parse_get(args, "read", &len); if (len && isalpha(param[0])) { @@ -1444,6 +1454,9 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in, const char * const use goto nope; } + //force full frame to all users with at least read + write(wakeuppipe[1], "", 1); + sprintf(buf, "HTTP/1.1 200 OK\r\n" "Server: KasmVNC/4.0\r\n" "Connection: close\r\n" diff --git a/common/rfb/VNCSConnectionST.cxx b/common/rfb/VNCSConnectionST.cxx index 1738330..1011e56 100644 --- a/common/rfb/VNCSConnectionST.cxx +++ b/common/rfb/VNCSConnectionST.cxx @@ -76,7 +76,7 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s, kasmpasswdpath[0] = '\0'; wordexp_t wexp; if (!wordexp(rfb::Server::kasmPasswordFile, &wexp, WRDE_NOCMD)) - strncpy(kasmpasswdpath, wexp.we_wordv[0], 4096); + strncpy(kasmpasswdpath, wexp.we_wordv[0], 4095); kasmpasswdpath[4095] = '\0'; wordfree(&wexp); diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index f440894..300eb4d 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -1181,3 +1181,13 @@ void VNCServerST::handleClipboardAnnounceBinary(VNCSConnectionST* client, clipboardClient = client; desktop->handleClipboardAnnounceBinary(num, mimes); } + +void VNCServerST::refreshClients() +{ + add_changed(pb->getRect()); + + std::list::iterator i; + for (i = clients.begin(); i != clients.end(); i++) { + (*i)->add_changed_all(); + } +} \ No newline at end of file diff --git a/common/rfb/VNCServerST.h b/common/rfb/VNCServerST.h index 21ce5a9..e36412a 100644 --- a/common/rfb/VNCServerST.h +++ b/common/rfb/VNCServerST.h @@ -43,7 +43,6 @@ namespace rfb { class ListConnInfo; class PixelBuffer; class KeyRemapper; - class network::GetAPIMessager; class VNCServerST : public VNCServer, public Timer::Callback, @@ -198,6 +197,8 @@ namespace rfb { void handleClipboardAnnounceBinary(VNCSConnectionST* client, const unsigned num, const char mimes[][32]); + void refreshClients(); + protected: friend class VNCSConnectionST; diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index 4c08fec..05f25f6 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -49,6 +49,8 @@ extern "C" { void vncSetGlueContext(int screenIndex); + +extern int wakeuppipe[2]; } using namespace rfb; @@ -307,6 +309,13 @@ void XserverDesktop::handleSocketEvent(int fd, bool read, bool write) { try { if (read) { + if (fd == wakeuppipe[0]) { + unsigned char buf; + while (::read(fd, &buf, 1) > 0); + server->refreshClients(); + return; + } + if (handleListenerEvent(fd, &listeners, server)) return; } diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc index 503b2b3..46f3ed1 100644 --- a/unix/xserver/hw/vnc/vncExtInit.cc +++ b/unix/xserver/hw/vnc/vncExtInit.cc @@ -17,8 +17,10 @@ * USA. */ +#include #include #include +#include #include #include @@ -49,6 +51,8 @@ extern "C" { void vncSetGlueContext(int screenIndex); + +int wakeuppipe[2]; } using namespace rfb; @@ -225,6 +229,11 @@ void vncExtensionInit(void) dummyY < 16) vncFatalError("Invalid value to %s", Server::maxVideoResolution.getName()); + pipe(wakeuppipe); + const int flags = fcntl(wakeuppipe[0], F_GETFL, 0); + fcntl(wakeuppipe[0], F_SETFL, flags | O_NONBLOCK); + vncSetNotifyFd(wakeuppipe[0], 0, true, false); + initialised = true; }