mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-11-25 09:33:50 +01:00
Apply read-only perms upon connecting
This commit is contained in:
parent
9a5afc5a62
commit
263d05a296
@ -123,11 +123,20 @@ WebSocket::WebSocket(int sock) : Socket(sock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char* WebSocket::getPeerAddress() {
|
char* WebSocket::getPeerAddress() {
|
||||||
return rfb::strDup("websocket");
|
struct sockaddr_un addr;
|
||||||
|
socklen_t len = sizeof(struct sockaddr_un);
|
||||||
|
if (getpeername(getFd(), (struct sockaddr *) &addr, &len) != 0) {
|
||||||
|
vlog.error("unable to get peer name for socket");
|
||||||
|
return rfb::strDup("websocket");
|
||||||
|
}
|
||||||
|
return rfb::strDup(addr.sun_path + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* WebSocket::getPeerEndpoint() {
|
char* WebSocket::getPeerEndpoint() {
|
||||||
return rfb::strDup("websocket");
|
char buf[1024];
|
||||||
|
sprintf(buf, "%s::websocket", getPeerAddress());
|
||||||
|
|
||||||
|
return rfb::strDup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -=- TcpSocket
|
// -=- TcpSocket
|
||||||
|
@ -107,7 +107,7 @@ ssize_t ws_send(ws_ctx_t *ctx, const void *buf, size_t len) {
|
|||||||
|
|
||||||
ws_ctx_t *alloc_ws_ctx() {
|
ws_ctx_t *alloc_ws_ctx() {
|
||||||
ws_ctx_t *ctx;
|
ws_ctx_t *ctx;
|
||||||
if (! (ctx = malloc(sizeof(ws_ctx_t))) )
|
if (! (ctx = calloc(sizeof(ws_ctx_t), 1)) )
|
||||||
{ fatal("malloc()"); }
|
{ fatal("malloc()"); }
|
||||||
|
|
||||||
if (! (ctx->cin_buf = malloc(BUFSIZE)) )
|
if (! (ctx->cin_buf = malloc(BUFSIZE)) )
|
||||||
@ -930,7 +930,8 @@ ws_ctx_t *do_handshake(int sock) {
|
|||||||
|
|
||||||
for (i = 0; i < set->num; i++) {
|
for (i = 0; i < set->num; i++) {
|
||||||
if (!strcmp(set->entries[i].user, inuser)) {
|
if (!strcmp(set->entries[i].user, inuser)) {
|
||||||
found = 1; // TODO write to wctx
|
found = 1;
|
||||||
|
strcpy(ws_ctx->user, inuser);
|
||||||
snprintf(authbuf, 4096, "%s:%s", set->entries[i].user,
|
snprintf(authbuf, 4096, "%s:%s", set->entries[i].user,
|
||||||
set->entries[i].password);
|
set->entries[i].password);
|
||||||
authbuf[4095] = '\0';
|
authbuf[4095] = '\0';
|
||||||
@ -1024,7 +1025,6 @@ void *subthread(void *ptr) {
|
|||||||
|
|
||||||
const int csock = pass->csock;
|
const int csock = pass->csock;
|
||||||
wsthread_handler_id = pass->id;
|
wsthread_handler_id = pass->id;
|
||||||
free((void *) pass);
|
|
||||||
|
|
||||||
ws_ctx_t *ws_ctx;
|
ws_ctx_t *ws_ctx;
|
||||||
|
|
||||||
@ -1034,11 +1034,14 @@ void *subthread(void *ptr) {
|
|||||||
goto out; // Child process exits
|
goto out; // Child process exits
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(ws_ctx->ip, pass->ip, sizeof(pass->ip));
|
||||||
|
|
||||||
proxy_handler(ws_ctx);
|
proxy_handler(ws_ctx);
|
||||||
if (pipe_error) {
|
if (pipe_error) {
|
||||||
handler_emsg("Closing due to SIGPIPE\n");
|
handler_emsg("Closing due to SIGPIPE\n");
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
free((void *) pass);
|
||||||
|
|
||||||
if (ws_ctx) {
|
if (ws_ctx) {
|
||||||
ws_socket_free(ws_ctx);
|
ws_socket_free(ws_ctx);
|
||||||
@ -1074,12 +1077,13 @@ void *start_server(void *unused) {
|
|||||||
error("ERROR on accept");
|
error("ERROR on accept");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
struct wspass_t *pass = calloc(1, sizeof(struct wspass_t));
|
||||||
|
inet_ntop(cli_addr.sin_family, &cli_addr.sin_addr, pass->ip, sizeof(pass->ip));
|
||||||
fprintf(stderr, " websocket %d: got client connection from %s\n",
|
fprintf(stderr, " websocket %d: got client connection from %s\n",
|
||||||
settings.handler_id,
|
settings.handler_id,
|
||||||
inet_ntoa(cli_addr.sin_addr));
|
pass->ip);
|
||||||
|
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
struct wspass_t *pass = calloc(1, sizeof(struct wspass_t));
|
|
||||||
pass->id = settings.handler_id;
|
pass->id = settings.handler_id;
|
||||||
pass->csock = csock;
|
pass->csock = csock;
|
||||||
pthread_create(&tid, NULL, subthread, pass);
|
pthread_create(&tid, NULL, subthread, pass);
|
||||||
|
@ -53,11 +53,15 @@ typedef struct {
|
|||||||
char *cout_buf;
|
char *cout_buf;
|
||||||
char *tin_buf;
|
char *tin_buf;
|
||||||
char *tout_buf;
|
char *tout_buf;
|
||||||
|
|
||||||
|
char user[32];
|
||||||
|
char ip[64];
|
||||||
} ws_ctx_t;
|
} ws_ctx_t;
|
||||||
|
|
||||||
struct wspass_t {
|
struct wspass_t {
|
||||||
int csock;
|
int csock;
|
||||||
unsigned id;
|
unsigned id;
|
||||||
|
char ip[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -227,7 +227,13 @@ void proxy_handler(ws_ctx_t *ws_ctx) {
|
|||||||
strcpy(addr.sun_path, ".KasmVNCSock");
|
strcpy(addr.sun_path, ".KasmVNCSock");
|
||||||
addr.sun_path[0] = '\0';
|
addr.sun_path[0] = '\0';
|
||||||
|
|
||||||
|
struct sockaddr_un myaddr;
|
||||||
|
myaddr.sun_family = AF_UNIX;
|
||||||
|
sprintf(myaddr.sun_path, ".%s@%s", ws_ctx->user, ws_ctx->ip);
|
||||||
|
myaddr.sun_path[0] = '\0';
|
||||||
|
|
||||||
int tsock = socket(AF_UNIX, SOCK_STREAM, 0);
|
int tsock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
bind(tsock, (struct sockaddr *) &myaddr, sizeof(struct sockaddr_un));
|
||||||
|
|
||||||
handler_msg("connecting to VNC target\n");
|
handler_msg("connecting to VNC target\n");
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
include_directories(${CMAKE_SOURCE_DIR}/common ${JPEG_INCLUDE_DIR})
|
include_directories(${CMAKE_SOURCE_DIR}/common ${JPEG_INCLUDE_DIR}
|
||||||
|
${CMAKE_SOURCE_DIR}/unix/kasmvncpasswd)
|
||||||
|
|
||||||
set(RFB_SOURCES
|
set(RFB_SOURCES
|
||||||
Blacklist.cxx
|
Blacklist.cxx
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <wordexp.h>
|
||||||
|
|
||||||
|
#include "kasmpasswd.h"
|
||||||
|
|
||||||
using namespace rfb;
|
using namespace rfb;
|
||||||
|
|
||||||
@ -45,6 +48,8 @@ static LogWriter vlog("VNCSConnST");
|
|||||||
|
|
||||||
static Cursor emptyCursor(0, 0, Point(0, 0), NULL);
|
static Cursor emptyCursor(0, 0, Point(0, 0), NULL);
|
||||||
|
|
||||||
|
extern rfb::StringParameter basicauth;
|
||||||
|
|
||||||
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
||||||
bool reverse)
|
bool reverse)
|
||||||
: sock(s), reverseConnection(reverse),
|
: sock(s), reverseConnection(reverse),
|
||||||
@ -65,6 +70,25 @@ VNCSConnectionST::VNCSConnectionST(VNCServerST* server_, network::Socket *s,
|
|||||||
memset(bstats_total, 0, sizeof(bstats_total));
|
memset(bstats_total, 0, sizeof(bstats_total));
|
||||||
gettimeofday(&connStart, NULL);
|
gettimeofday(&connStart, NULL);
|
||||||
|
|
||||||
|
// Check their permissions, if applicable
|
||||||
|
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);
|
||||||
|
|
||||||
|
user[0] = '\0';
|
||||||
|
const char *at = strchr(peerEndpoint.buf, '@');
|
||||||
|
if (at && at - peerEndpoint.buf > 1 && at - peerEndpoint.buf < 32) {
|
||||||
|
memcpy(user, peerEndpoint.buf, at - peerEndpoint.buf);
|
||||||
|
user[at - peerEndpoint.buf] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool write, owner;
|
||||||
|
if (!getPerms(write, owner) || !write)
|
||||||
|
accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents));
|
||||||
|
|
||||||
// Configure the socket
|
// Configure the socket
|
||||||
setSocketTimeouts();
|
setSocketTimeouts();
|
||||||
lastEventTime = time(0);
|
lastEventTime = time(0);
|
||||||
@ -999,6 +1023,29 @@ bool VNCSConnectionST::isShiftPressed()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VNCSConnectionST::getPerms(bool &write, bool &owner) const
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
const char *colon = strchr(basicauth, ':');
|
||||||
|
if (colon && !colon[1] && user[0]) {
|
||||||
|
struct kasmpasswd_t *set = readkasmpasswd(kasmpasswdpath);
|
||||||
|
unsigned i;
|
||||||
|
for (i = 0; i < set->num; i++) {
|
||||||
|
if (!strcmp(set->entries[i].user, user)) {
|
||||||
|
write = set->entries[i].write;
|
||||||
|
owner = set->entries[i].owner;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(set->entries);
|
||||||
|
free(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void VNCSConnectionST::writeRTTPing()
|
void VNCSConnectionST::writeRTTPing()
|
||||||
{
|
{
|
||||||
char type;
|
char type;
|
||||||
|
@ -184,7 +184,13 @@ namespace rfb {
|
|||||||
// of a VNCSConnectioST to the server. These access rights are applied
|
// of a VNCSConnectioST to the server. These access rights are applied
|
||||||
// such that the actual rights granted are the minimum of the server's
|
// such that the actual rights granted are the minimum of the server's
|
||||||
// default access settings and the connection's access settings.
|
// default access settings and the connection's access settings.
|
||||||
virtual void setAccessRights(AccessRights ar) {accessRights=ar;}
|
virtual void setAccessRights(AccessRights ar) {
|
||||||
|
accessRights = ar;
|
||||||
|
|
||||||
|
bool write, owner;
|
||||||
|
if (!getPerms(write, owner) || !write)
|
||||||
|
accessRights = (accessRights & ~(AccessPtrEvents | AccessKeyEvents));
|
||||||
|
}
|
||||||
|
|
||||||
// Timer callbacks
|
// Timer callbacks
|
||||||
virtual bool handleTimeout(Timer* t);
|
virtual bool handleTimeout(Timer* t);
|
||||||
@ -193,6 +199,8 @@ namespace rfb {
|
|||||||
|
|
||||||
bool isShiftPressed();
|
bool isShiftPressed();
|
||||||
|
|
||||||
|
bool getPerms(bool &write, bool &owner) const;
|
||||||
|
|
||||||
// Congestion control
|
// Congestion control
|
||||||
void writeRTTPing();
|
void writeRTTPing();
|
||||||
bool isCongested();
|
bool isCongested();
|
||||||
@ -249,6 +257,9 @@ namespace rfb {
|
|||||||
rdr::U64 bstats_total[BS_NUM];
|
rdr::U64 bstats_total[BS_NUM];
|
||||||
struct timeval connStart;
|
struct timeval connStart;
|
||||||
|
|
||||||
|
char user[32];
|
||||||
|
char kasmpasswdpath[4096];
|
||||||
|
|
||||||
time_t lastEventTime;
|
time_t lastEventTime;
|
||||||
time_t pointerEventTime;
|
time_t pointerEventTime;
|
||||||
Point pointerEventPos;
|
Point pointerEventPos;
|
||||||
|
Loading…
Reference in New Issue
Block a user