Merge branch 'feature/KASM-2863-clipboard-api-redo' into 'master'

Add clear_clipboard API

Closes KASM-2863

See merge request kasm-technologies/internal/KasmVNC!86
This commit is contained in:
Matthew McClaskey 2023-01-11 11:13:30 +00:00
commit f1104e2cb5
12 changed files with 105 additions and 5 deletions

View File

@ -66,6 +66,7 @@ namespace network {
void netResetFrameStatsCall();
uint8_t netServerFrameStatsReady();
void netUdpUpgrade(void *client, uint32_t ip);
void netClearClipboard();
enum USER_ACTION {
NONE,
@ -73,7 +74,8 @@ namespace network {
WANT_FRAME_STATS_ALL,
WANT_FRAME_STATS_OWNER,
WANT_FRAME_STATS_SPECIFIC,
UDP_UPGRADE
UDP_UPGRADE,
CLEAR_CLIPBOARD,
};
uint8_t netRequestFrameStats(USER_ACTION what, const char *client);

View File

@ -806,3 +806,16 @@ void GetAPIMessager::netUdpUpgrade(void *client, uint32_t ip) {
pthread_mutex_unlock(&userMutex);
}
void GetAPIMessager::netClearClipboard() {
action_data act;
act.action = CLEAR_CLIPBOARD;
// Send it in
if (pthread_mutex_lock(&userMutex))
return;
actionQueue.push_back(act);
pthread_mutex_unlock(&userMutex);
}

View File

@ -545,6 +545,12 @@ static uint8_t serverFrameStatsReadyCb(void *messager)
return msgr->netServerFrameStatsReady();
}
static void clearClipboardCb(void *messager)
{
GetAPIMessager *msgr = (GetAPIMessager *) messager;
msgr->netClearClipboard();
}
#if OPENSSL_VERSION_NUMBER < 0x1010000f
static pthread_mutex_t *sslmutex;
@ -693,6 +699,8 @@ WebsocketListener::WebsocketListener(const struct sockaddr *listenaddr,
settings.getClientFrameStatsNumCb = getClientFrameStatsNumCb;
settings.serverFrameStatsReadyCb = serverFrameStatsReadyCb;
settings.clearClipboardCb = clearClipboardCb;
openssl_threads();
pthread_t tid;

View File

@ -1596,6 +1596,22 @@ static uint8_t ownerapi(ws_ctx_t *ws_ctx, const char *in, const char * const use
ws_send(ws_ctx, buf, strlen(buf));
weblog(200, wsthread_handler_id, 0, origip, ip, user, 1, origpath, strlen(buf));
ret = 1;
} else entry("/api/clear_clipboard") {
settings.clearClipboardCb(settings.messager);
write(wakeuppipe[1], "", 1);
sprintf(buf, "HTTP/1.1 200 OK\r\n"
"Server: KasmVNC/4.0\r\n"
"Connection: close\r\n"
"Content-type: text/plain\r\n"
"Content-length: 6\r\n"
"%s"
"\r\n"
"200 OK", extra_headers ? extra_headers : "");
ws_send(ws_ctx, buf, strlen(buf));
weblog(200, wsthread_handler_id, 0, origip, ip, user, 1, origpath, strlen(buf));
ret = 1;
}

View File

@ -105,6 +105,8 @@ typedef struct {
void (*getUsersCb)(void *messager, const char **buf);
uint8_t (*getClientFrameStatsNumCb)(void *messager);
uint8_t (*serverFrameStatsReadyCb)(void *messager);
void (*clearClipboardCb)(void *messager);
} settings_t;
#ifdef __cplusplus

View File

@ -86,6 +86,8 @@ namespace rfb {
virtual void handleClipboardAnnounceBinary(const unsigned __unused_attr num,
const char __unused_attr mimes[][32]) {}
virtual void clearLocalClipboards() {}
protected:
virtual ~SDesktop() {}
};

View File

@ -832,9 +832,8 @@ static void upgradeClientToUdp(const network::GetAPIMessager::action_data &act,
}
}
static void checkAPIMessages(network::GetAPIMessager *apimessager,
rdr::U8 &trackingFrameStats, char trackingClient[],
std::list<VNCSConnectionST*> &clients)
void VNCServerST::checkAPIMessages(network::GetAPIMessager *apimessager,
rdr::U8 &trackingFrameStats, char trackingClient[])
{
if (pthread_mutex_lock(&apimessager->userMutex))
return;
@ -866,6 +865,15 @@ static void checkAPIMessages(network::GetAPIMessager *apimessager,
case network::GetAPIMessager::UDP_UPGRADE:
upgradeClientToUdp(act, clients);
break;
case network::GetAPIMessager::CLEAR_CLIPBOARD:
clearBinaryClipboardData();
clipboardClient = NULL;
desktop->handleClipboardAnnounceBinary(0, NULL);
sendBinaryClipboardData("text/plain", NULL, 0);
desktop->clearLocalClipboards();
break;
}
}
@ -1031,7 +1039,7 @@ void VNCServerST::writeUpdate()
shottime = msSince(&shotstart);
trackingFrameStats = 0;
checkAPIMessages(apimessager, trackingFrameStats, trackingClient, clients);
checkAPIMessages(apimessager, trackingFrameStats, trackingClient);
}
const rdr::U8 origtrackingFrameStats = trackingFrameStats;

View File

@ -284,6 +284,9 @@ namespace rfb {
void translateDLPRegion(rdr::U16 &x1, rdr::U16 &y1, rdr::U16 &x2, rdr::U16 &y2) const;
rdr::U32 clipboardId;
void checkAPIMessages(network::GetAPIMessager *apimessager,
rdr::U8 &trackingFrameStats, char trackingClient[]);
};
};

View File

@ -182,6 +182,11 @@ XserverDesktop::queryConnection(network::Socket* sock,
return rfb::VNCServerST::PENDING;
}
void XserverDesktop::clearLocalClipboards()
{
vncClearLocalClipboards();
}
void XserverDesktop::announceClipboard(bool available)
{
try {

View File

@ -61,6 +61,7 @@ public:
void setFramebuffer(int w, int h, void* fbptr, int stride);
void refreshScreenLayout();
void requestClipboard();
void clearLocalClipboards();
void announceClipboard(bool available);
void clearBinaryClipboardData();
void sendBinaryClipboardData(const char* mime, const unsigned char *data,

View File

@ -763,3 +763,42 @@ static void vncClientStateCallback(CallbackListPtr * l,
}
}
}
static void vncClearLocalClipboard(Atom selection)
{
SelectionInfoRec info;
Selection *pSel;
int rc;
rc = dixLookupSelection(&pSel, selection, serverClient, DixSetAttrAccess);
if (rc != Success)
return;
if (pSel->client && (pSel->client != serverClient)) {
xEvent event = {
.u.selectionClear.time = currentTime.milliseconds,
.u.selectionClear.window = pSel->window,
.u.selectionClear.atom = pSel->selection
};
event.u.u.type = SelectionClear;
WriteEventsToClient(pSel->client, 1, &event);
}
pSel->lastTimeChanged = currentTime;
pSel->window = None;
pSel->pWin = NULL;
pSel->client = NullClient;
LOG_DEBUG("Cleared %s selection", NameForAtom(selection));
info.selection = pSel;
info.client = serverClient;
info.kind = SelectionSetOwner;
CallCallbacks(&SelectionCallback, &info);
}
void vncClearLocalClipboards()
{
vncClearLocalClipboard(xaPRIMARY);
vncClearLocalClipboard(xaCLIPBOARD);
}

View File

@ -26,6 +26,7 @@ void vncSelectionInit(void);
void vncHandleClipboardAnnounce(int available);
void vncHandleClipboardAnnounceBinary(const unsigned num, const char mimes[][32]);
void vncClearLocalClipboards();
#ifdef __cplusplus
}