commit 615cc243b61833bc46c7233557e83c17423ed6fe Author: Toshaan Bharvani Date: Tue Jun 14 18:36:59 2022 +0200 initial package creation Signed-off-by: Toshaan Bharvani diff --git a/SOURCES/0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch b/SOURCES/0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch new file mode 100644 index 0000000..5d85b09 --- /dev/null +++ b/SOURCES/0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch @@ -0,0 +1,241 @@ +From e4849b01fec4494057728d1aa3a165ed21705682 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 11 Jun 2018 23:47:02 +0200 +Subject: [PATCH 1/4] libvncserver: Add API to add custom I/O entry points + +Add API to make it possible to channel RFB input and output through +another layer, for example TLS. This is done by making it possible to +override the default read/write/peek functions. +--- + libvncserver/rfbserver.c | 4 ++ + libvncserver/sockets.c | 79 ++++++++++++++++++++++++++++++++++++---- + rfb/rfb.h | 17 +++++++++ + 3 files changed, 93 insertions(+), 7 deletions(-) + +diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c +index e9eaa5fc..72e9ba79 100644 +--- a/libvncserver/rfbserver.c ++++ b/libvncserver/rfbserver.c +@@ -319,6 +319,10 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, + + cl->screen = rfbScreen; + cl->sock = sock; ++ cl->readFromSocket = rfbDefaultReadFromSocket; ++ cl->peekAtSocket = rfbDefaultPeekAtSocket; ++ cl->hasPendingOnSocket = rfbDefaultHasPendingOnSocket; ++ cl->writeToSocket = rfbDefaultWriteToSocket; + cl->viewOnly = FALSE; + /* setup pseudo scaling */ + cl->scaledScreen = rfbScreen; +diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c +index 2c87376b..4bb881ec 100644 +--- a/libvncserver/sockets.c ++++ b/libvncserver/sockets.c +@@ -101,6 +101,9 @@ int deny_severity=LOG_WARNING; + int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has + gone away - needed to stop us hanging */ + ++static rfbBool ++rfbHasPendingOnSocket(rfbClientPtr cl); ++ + static rfbBool + rfbNewConnectionFromSock(rfbScreenInfoPtr rfbScreen, rfbSocket sock) + { +@@ -364,16 +367,20 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) + tv.tv_usec = usec; + nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv); + if (nfds == 0) { ++ rfbBool hasPendingData = FALSE; ++ + /* timed out, check for async events */ + i = rfbGetClientIterator(rfbScreen); + while((cl = rfbClientIteratorNext(i))) { + if (cl->onHold) + continue; ++ hasPendingData |= rfbHasPendingOnSocket(cl); + if (FD_ISSET(cl->sock, &(rfbScreen->allFds))) + rfbSendFileTransferChunk(cl); + } + rfbReleaseClientIterator(i); +- return result; ++ if (!hasPendingData) ++ return result; + } + + if (nfds < 0) { +@@ -449,9 +456,11 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec) + if (cl->onHold) + continue; + +- if (FD_ISSET(cl->sock, &(rfbScreen->allFds))) ++ if (rfbHasPendingOnSocket (cl) || ++ FD_ISSET(cl->sock, &(rfbScreen->allFds))) + { +- if (FD_ISSET(cl->sock, &fds)) ++ if (rfbHasPendingOnSocket (cl) || ++ FD_ISSET(cl->sock, &fds)) + { + #ifdef LIBVNCSERVER_WITH_WEBSOCKETS + do { +@@ -614,6 +623,30 @@ rfbConnect(rfbScreenInfoPtr rfbScreen, + return sock; + } + ++int ++rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len) ++{ ++ return read(cl->sock, buf, len); ++} ++ ++static int ++rfbReadFromSocket(rfbClientPtr cl, char *buf, int len) ++{ ++ return cl->readFromSocket(cl, buf, len); ++} ++ ++rfbBool ++rfbDefaultHasPendingOnSocket(rfbClientPtr cl) ++{ ++ return FALSE; ++} ++ ++static rfbBool ++rfbHasPendingOnSocket(rfbClientPtr cl) ++{ ++ return cl->hasPendingOnSocket(cl); ++} ++ + /* + * ReadExact reads an exact number of bytes from a client. Returns 1 if + * those bytes have been read, 0 if the other end has closed, or -1 if an error +@@ -635,10 +668,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout) + } else if (cl->sslctx) { + n = rfbssl_read(cl, buf, len); + } else { +- n = read(sock, buf, len); ++ n = rfbReadFromSocket(cl, buf, len); + } + #else +- n = read(sock, buf, len); ++ n = rfbReadFromSocket(cl, buf, len); + #endif + + if (n > 0) { +@@ -670,6 +703,10 @@ rfbReadExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout) + continue; + } + #endif ++ ++ if (rfbHasPendingOnSocket(cl)) ++ continue; ++ + FD_ZERO(&fds); + FD_SET(sock, &fds); + tv.tv_sec = timeout / 1000; +@@ -706,6 +743,18 @@ int rfbReadExact(rfbClientPtr cl,char* buf,int len) + return(rfbReadExactTimeout(cl,buf,len,rfbMaxClientWait)); + } + ++int ++rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len) ++{ ++ return recv(cl->sock, buf, len, MSG_PEEK); ++} ++ ++int ++rfbPeekAtSocket(rfbClientPtr cl, char *buf, int len) ++{ ++ cl->peekAtSocket(cl, buf, len); ++} ++ + /* + * PeekExact peeks at an exact number of bytes from a client. Returns 1 if + * those bytes have been read, 0 if the other end has closed, or -1 if an +@@ -726,7 +775,7 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout) + n = rfbssl_peek(cl, buf, len); + else + #endif +- n = recv(sock, buf, len, MSG_PEEK); ++ n = rfbPeekAtSocket(cl, buf, len); + + if (n == len) { + +@@ -782,6 +831,22 @@ rfbPeekExactTimeout(rfbClientPtr cl, char* buf, int len, int timeout) + return 1; + } + ++int ++rfbDefaultWriteToSocket(rfbClientPtr cl, ++ const char *buf, ++ int len) ++{ ++ return write(cl->sock, buf, len); ++} ++ ++static int ++rfbWriteToSocket(rfbClientPtr cl, ++ const char *buf, ++ int len) ++{ ++ return cl->writeToSocket(cl, buf, len); ++} ++ + /* + * WriteExact writes an exact number of bytes to a client. Returns 1 if + * those bytes have been written, or -1 if an error occurred (errno is set to +@@ -826,7 +891,7 @@ rfbWriteExact(rfbClientPtr cl, + n = rfbssl_write(cl, buf, len); + else + #endif +- n = write(sock, buf, len); ++ n = rfbWriteToSocket(cl, buf, len); + + if (n > 0) { + +diff --git a/rfb/rfb.h b/rfb/rfb.h +index 5e9ba86f..3c0b25a3 100644 +--- a/rfb/rfb.h ++++ b/rfb/rfb.h +@@ -387,6 +387,14 @@ typedef struct sraRegion* sraRegionPtr; + typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl); + typedef void (*ClientFramebufferUpdateRequestHookPtr)(struct _rfbClientRec* cl, rfbFramebufferUpdateRequestMsg* furMsg); + ++typedef int (*ClientReadFromSocket)(struct _rfbClientRec* cl, ++ char *buf, int len); ++typedef int (*ClientPeekAtSocket)(struct _rfbClientRec* cl, ++ char *buf, int len); ++typedef rfbBool (*ClientHasPendingOnSocket)(struct _rfbClientRec* cl); ++typedef int (*ClientWriteToSocket)(struct _rfbClientRec* cl, ++ const char *buf, int len); ++ + typedef struct _rfbFileTransferData { + int fd; + int compressionEnabled; +@@ -680,6 +688,11 @@ typedef struct _rfbClientRec { + rfbBool useExtDesktopSize; + int requestedDesktopSizeChange; + int lastDesktopSizeChangeError; ++ ++ ClientReadFromSocket readFromSocket; /* Read data from socket */ ++ ClientPeekAtSocket peekAtSocket; /* Peek at data from socket */ ++ ClientHasPendingOnSocket hasPendingOnSocket; /* Peek at data from socket */ ++ ClientWriteToSocket writeToSocket; /* Write data to socket */ + } rfbClientRec, *rfbClientPtr; + + /** +@@ -732,8 +745,12 @@ extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen); + extern void rfbCloseClient(rfbClientPtr cl); + extern int rfbReadExact(rfbClientPtr cl, char *buf, int len); + extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout); ++extern int rfbDefaultReadFromSocket(rfbClientPtr cl, char *buf, int len); + extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout); ++extern int rfbDefaultPeekAtSocket(rfbClientPtr cl, char *buf, int len); ++extern rfbBool rfbDefaultHasPendingOnSocket(rfbClientPtr cl); + extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len); ++extern int rfbDefaultWriteToSocket(rfbClientPtr cl, const char *buf, int len); + extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec); + extern rfbSocket rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port); + extern rfbSocket rfbConnectToTcpAddr(char* host, int port); +-- +2.28.0 + diff --git a/SOURCES/0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch b/SOURCES/0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch new file mode 100644 index 0000000..11d0f7e --- /dev/null +++ b/SOURCES/0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch @@ -0,0 +1,28 @@ +From d138cf90130b0e8d5062f136ecdbcaa85e734d5d Mon Sep 17 00:00:00 2001 +From: Christian Beier +Date: Mon, 20 Jul 2020 22:33:29 +0200 +Subject: [PATCH] libvncserver: don't NULL out internal of the default cursor + +...otherwise an rfbScreen created after rfbScreenCleanup() was called +gets assigned an invalid cursor struct. +--- + libvncserver/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libvncserver/main.c b/libvncserver/main.c +index 9149fda3..a3a711e3 100644 +--- a/libvncserver/main.c ++++ b/libvncserver/main.c +@@ -1110,7 +1110,8 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen) + FREE_IF(underCursorBuffer); + TINI_MUTEX(screen->cursorMutex); + +- rfbFreeCursor(screen->cursor); ++ if(screen->cursor != &myCursor) ++ rfbFreeCursor(screen->cursor); + + #ifdef LIBVNCSERVER_HAVE_LIBZ + rfbZlibCleanup(screen); +-- +2.28.0 + diff --git a/SOURCES/0002-libvncserver-Add-channel-security-handlers.patch b/SOURCES/0002-libvncserver-Add-channel-security-handlers.patch new file mode 100644 index 0000000..eb2aa9f --- /dev/null +++ b/SOURCES/0002-libvncserver-Add-channel-security-handlers.patch @@ -0,0 +1,368 @@ +From c9131a78878a785c3de21e9d49521d7b68400ad7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Mon, 11 Jun 2018 23:50:05 +0200 +Subject: [PATCH 2/4] libvncserver: Add channel security handlers + +Add another type of security handler that is meant to be used initially +to set up a secure channel. Regular security handlers would be +advertised and processed after any channel security have succeeded. + +For example, this, together with the custom I/O functions allows a +LibVNCServer user to implement TLS in combination with VNCAuth. This is +done by adding a single channel security handler with the rfbTLS (18) +with a handler that initiates a TLS session, and when a TLS session is +initiated, the regular security handler list is sent. +--- + libvncserver/auth.c | 164 ++++++++++++++++++++++++++++++--------- + libvncserver/rfbserver.c | 1 + + rfb/rfb.h | 15 +++- + 3 files changed, 142 insertions(+), 38 deletions(-) + +diff --git a/libvncserver/auth.c b/libvncserver/auth.c +index 814a8142..55e0b3c9 100644 +--- a/libvncserver/auth.c ++++ b/libvncserver/auth.c +@@ -37,18 +37,17 @@ void rfbClientSendString(rfbClientPtr cl, const char *reason); + * Handle security types + */ + ++/* Channel security handlers to set up a secure channel, e.g. TLS. */ ++static rfbSecurityHandler* channelSecurityHandlers = NULL; ++ ++/* Security handlers when channel security is established. */ + static rfbSecurityHandler* securityHandlers = NULL; + +-/* +- * This method registers a list of new security types. +- * It avoids same security type getting registered multiple times. +- * The order is not preserved if multiple security types are +- * registered at one-go. +- */ + void +-rfbRegisterSecurityHandler(rfbSecurityHandler* handler) ++rfbRegisterSecurityHandlerTo(rfbSecurityHandler* handler, ++ rfbSecurityHandler** handlerList) + { +- rfbSecurityHandler *head = securityHandlers, *next = NULL; ++ rfbSecurityHandler *head = *handlerList, *next = NULL; + + if(handler == NULL) + return; +@@ -57,39 +56,35 @@ rfbRegisterSecurityHandler(rfbSecurityHandler* handler) + + while(head != NULL) { + if(head == handler) { +- rfbRegisterSecurityHandler(next); ++ rfbRegisterSecurityHandlerTo(next, handlerList); + return; + } + + head = head->next; + } + +- handler->next = securityHandlers; +- securityHandlers = handler; ++ handler->next = *handlerList; ++ *handlerList = handler; + +- rfbRegisterSecurityHandler(next); ++ rfbRegisterSecurityHandlerTo(next, handlerList); + } + +-/* +- * This method unregisters a list of security types. +- * These security types won't be available for any new +- * client connection. +- */ +-void +-rfbUnregisterSecurityHandler(rfbSecurityHandler* handler) ++static void ++rfbUnregisterSecurityHandlerFrom(rfbSecurityHandler* handler, ++ rfbSecurityHandler** handlerList) + { + rfbSecurityHandler *cur = NULL, *pre = NULL; + + if(handler == NULL) + return; + +- if(securityHandlers == handler) { +- securityHandlers = securityHandlers->next; +- rfbUnregisterSecurityHandler(handler->next); ++ if(*handlerList == handler) { ++ *handlerList = (*handlerList)->next; ++ rfbUnregisterSecurityHandlerFrom(handler->next, handlerList); + return; + } + +- cur = pre = securityHandlers; ++ cur = pre = *handlerList; + + while(cur) { + if(cur == handler) { +@@ -99,7 +94,50 @@ rfbUnregisterSecurityHandler(rfbSecurityHandler* handler) + pre = cur; + cur = cur->next; + } +- rfbUnregisterSecurityHandler(handler->next); ++ rfbUnregisterSecurityHandlerFrom(handler->next, handlerList); ++} ++ ++void ++rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler) ++{ ++ rfbRegisterSecurityHandlerTo(handler, &channelSecurityHandlers); ++} ++ ++/* ++ * This method unregisters a list of security types. ++ * These security types won't be available for any new ++ * client connection. ++ */ ++ ++void ++rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler) ++{ ++ rfbUnregisterSecurityHandlerFrom(handler, &channelSecurityHandlers); ++} ++ ++/* ++ * This method registers a list of new security types. ++ * It avoids same security type getting registered multiple times. ++ * The order is not preserved if multiple security types are ++ * registered at one-go. ++ */ ++ ++void ++rfbRegisterSecurityHandler(rfbSecurityHandler* handler) ++{ ++ rfbRegisterSecurityHandlerTo(handler, &securityHandlers); ++} ++ ++/* ++ * This method unregisters a list of security types. ++ * These security types won't be available for any new ++ * client connection. ++ */ ++ ++void ++rfbUnregisterSecurityHandler(rfbSecurityHandler* handler) ++{ ++ rfbUnregisterSecurityHandlerFrom(handler, &securityHandlers); + } + + /* +@@ -197,9 +235,22 @@ static rfbSecurityHandler VncSecurityHandlerNone = { + NULL + }; + ++static int32_t ++determinePrimarySecurityType(rfbClientPtr cl) ++{ ++ if (!cl->screen->authPasswdData || cl->reverseConnection) { ++ /* chk if this condition is valid or not. */ ++ return rfbSecTypeNone; ++ } else if (cl->screen->authPasswdData) { ++ return rfbSecTypeVncAuth; ++ } else { ++ return rfbSecTypeInvalid; ++ } ++} + +-static void +-rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) ++void ++rfbSendSecurityTypeList(rfbClientPtr cl, ++ enum rfbSecurityTag exclude) + { + /* The size of the message is the count of security types +1, + * since the first byte is the number of types. */ +@@ -207,9 +258,10 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) + rfbSecurityHandler* handler; + #define MAX_SECURITY_TYPES 255 + uint8_t buffer[MAX_SECURITY_TYPES+1]; +- ++ int32_t primaryType; + + /* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */ ++ primaryType = determinePrimarySecurityType(cl); + switch (primaryType) { + case rfbSecTypeNone: + rfbRegisterSecurityHandler(&VncSecurityHandlerNone); +@@ -221,6 +273,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) + + for (handler = securityHandlers; + handler && sizenext) { ++ if (exclude && (handler->securityTags & exclude)) ++ continue; ++ + buffer[size] = handler->type; + size++; + } +@@ -249,7 +304,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType) + cl->state = RFB_SECURITY_TYPE; + } + ++static void ++rfbSendChannelSecurityTypeList(rfbClientPtr cl) ++{ ++ int size = 1; ++ rfbSecurityHandler* handler; ++ uint8_t buffer[MAX_SECURITY_TYPES+1]; ++ ++ for (handler = channelSecurityHandlers; ++ handler && sizenext) { ++ buffer[size] = handler->type; ++ size++; ++ } ++ buffer[0] = (unsigned char)size-1; ++ ++ if (rfbWriteExact(cl, (char *)buffer, size) < 0) { ++ rfbLogPerror("rfbSendSecurityTypeList: write"); ++ rfbCloseClient(cl); ++ return; ++ } + ++ /* Dispatch client input to rfbProcessClientChannelSecurityType. */ ++ cl->state = RFB_CHANNEL_SECURITY_TYPE; ++} + + + /* +@@ -297,18 +374,19 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType) + void + rfbAuthNewClient(rfbClientPtr cl) + { +- int32_t securityType = rfbSecTypeInvalid; ++ int32_t securityType; + +- if (!cl->screen->authPasswdData || cl->reverseConnection) { +- /* chk if this condition is valid or not. */ +- securityType = rfbSecTypeNone; +- } else if (cl->screen->authPasswdData) { +- securityType = rfbSecTypeVncAuth; +- } ++ securityType = determinePrimarySecurityType(cl); + + if (cl->protocolMajorVersion==3 && cl->protocolMinorVersion < 7) + { + /* Make sure we use only RFB 3.3 compatible security types. */ ++ if (channelSecurityHandlers) { ++ rfbLog("VNC channel security enabled - RFB 3.3 client rejected\n"); ++ rfbClientConnFailed(cl, "Your viewer cannot hnadler required " ++ "security methods"); ++ return; ++ } + if (securityType == rfbSecTypeInvalid) { + rfbLog("VNC authentication disabled - RFB 3.3 client rejected\n"); + rfbClientConnFailed(cl, "Your viewer cannot handle required " +@@ -316,9 +394,13 @@ rfbAuthNewClient(rfbClientPtr cl) + return; + } + rfbSendSecurityType(cl, securityType); ++ } else if (channelSecurityHandlers) { ++ rfbLog("Send channel security type list\n"); ++ rfbSendChannelSecurityTypeList(cl); + } else { + /* Here it's ok when securityType is set to rfbSecTypeInvalid. */ +- rfbSendSecurityTypeList(cl, securityType); ++ rfbLog("Send channel security type 'none'\n"); ++ rfbSendSecurityTypeList(cl, RFB_SECURITY_TAG_NONE); + } + } + +@@ -332,6 +414,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl) + int n; + uint8_t chosenType; + rfbSecurityHandler* handler; ++ rfbSecurityHandler* handlerListHead; + + /* Read the security type. */ + n = rfbReadExact(cl, (char *)&chosenType, 1); +@@ -344,8 +427,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl) + return; + } + ++ switch (cl->state) { ++ case RFB_CHANNEL_SECURITY_TYPE: ++ handlerListHead = channelSecurityHandlers; ++ break; ++ case RFB_SECURITY_TYPE: ++ handlerListHead = securityHandlers; ++ break; ++ } ++ + /* Make sure it was present in the list sent by the server. */ +- for (handler = securityHandlers; handler; handler = handler->next) { ++ for (handler = handlerListHead; handler; handler = handler->next) { + if (chosenType == handler->type) { + rfbLog("rfbProcessClientSecurityType: executing handler for type %d\n", chosenType); + handler->handler(cl); +diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c +index 72e9ba79..48eada64 100644 +--- a/libvncserver/rfbserver.c ++++ b/libvncserver/rfbserver.c +@@ -652,6 +652,7 @@ rfbProcessClientMessage(rfbClientPtr cl) + case RFB_PROTOCOL_VERSION: + rfbProcessClientProtocolVersion(cl); + return; ++ case RFB_CHANNEL_SECURITY_TYPE: + case RFB_SECURITY_TYPE: + rfbProcessClientSecurityType(cl); + return; +diff --git a/rfb/rfb.h b/rfb/rfb.h +index 3c0b25a3..d136f884 100644 +--- a/rfb/rfb.h ++++ b/rfb/rfb.h +@@ -144,6 +144,11 @@ typedef struct { + } data; /**< there have to be count*3 entries */ + } rfbColourMap; + ++enum rfbSecurityTag { ++ RFB_SECURITY_TAG_NONE = 0, ++ RFB_SECURITY_TAG_CHANNEL = 1 << 0 ++}; ++ + /** + * Security handling (RFB protocol version 3.7) + */ +@@ -152,6 +157,7 @@ typedef struct _rfbSecurity { + uint8_t type; + void (*handler)(struct _rfbClientRec* cl); + struct _rfbSecurity* next; ++ enum rfbSecurityTag securityTags; + } rfbSecurityHandler; + + /** +@@ -480,7 +486,7 @@ typedef struct _rfbClientRec { + /** Possible client states: */ + enum { + RFB_PROTOCOL_VERSION, /**< establishing protocol version */ +- RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */ ++ RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */ + RFB_AUTHENTICATION, /**< authenticating */ + RFB_INITIALISATION, /**< sending initialisation messages */ + RFB_NORMAL, /**< normal protocol messages */ +@@ -488,7 +494,9 @@ typedef struct _rfbClientRec { + /* Ephemeral internal-use states that will never be seen by software + * using LibVNCServer to provide services: */ + +- RFB_INITIALISATION_SHARED /**< sending initialisation messages with implicit shared-flag already true */ ++ RFB_INITIALISATION_SHARED, /**< sending initialisation messages with implicit shared-flag already true */ ++ ++ RFB_CHANNEL_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */ + } state; + + rfbBool reverseConnection; +@@ -840,6 +848,9 @@ extern void rfbProcessClientSecurityType(rfbClientPtr cl); + extern void rfbAuthProcessClientMessage(rfbClientPtr cl); + extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler); + extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler); ++extern void rfbRegisterChannelSecurityHandler(rfbSecurityHandler* handler); ++extern void rfbUnregisterChannelSecurityHandler(rfbSecurityHandler* handler); ++extern void rfbSendSecurityTypeList(rfbClientPtr cl, enum rfbSecurityTag exclude); + + /* rre.c */ + +-- +2.28.0 + diff --git a/SOURCES/0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch b/SOURCES/0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch new file mode 100644 index 0000000..2f736d0 --- /dev/null +++ b/SOURCES/0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch @@ -0,0 +1,32 @@ +From 2a77dd86a97fa5f4735f678599cea839ba09009c Mon Sep 17 00:00:00 2001 +From: Christian Beier +Date: Sun, 9 Aug 2020 20:11:26 +0200 +Subject: [PATCH 3/4] libvncserver/auth: don't keep security handlers from + previous runs + +Whyohsoever security handlers are stored in a variable global to the +application, not in the rfbScreen struct. This meant that security +handlers registered once would stick around forever before this commit. +--- + libvncserver/auth.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libvncserver/auth.c b/libvncserver/auth.c +index 55e0b3c9..fc74c800 100644 +--- a/libvncserver/auth.c ++++ b/libvncserver/auth.c +@@ -264,9 +264,11 @@ rfbSendSecurityTypeList(rfbClientPtr cl, + primaryType = determinePrimarySecurityType(cl); + switch (primaryType) { + case rfbSecTypeNone: ++ rfbUnregisterSecurityHandler(&VncSecurityHandlerVncAuth); + rfbRegisterSecurityHandler(&VncSecurityHandlerNone); + break; + case rfbSecTypeVncAuth: ++ rfbUnregisterSecurityHandler(&VncSecurityHandlerNone); + rfbRegisterSecurityHandler(&VncSecurityHandlerVncAuth); + break; + } +-- +2.28.0 + diff --git a/SOURCES/0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch b/SOURCES/0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch new file mode 100644 index 0000000..d45dfeb --- /dev/null +++ b/SOURCES/0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch @@ -0,0 +1,45 @@ +From 641610b961a732bb68f111536ebf8c42be20f05b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Wed, 16 Sep 2020 17:35:49 +0200 +Subject: [PATCH 4/4] zlib: Clear buffer pointers on cleanup (#444) + +The pointers to the buffers were freed, and the size fields were set to +0, but the buffer pointers themsef was not set to NULL, when shutting +down, meaning the next time used, NULL checks would not tell whether the +pointer is valid. This caused crashes ending with + + #0 0x00007ffff73729e5 in raise () from /lib64/libc.so.6 + #1 0x00007ffff735b895 in abort () from /lib64/libc.so.6 + #2 0x00007ffff73b6857 in __libc_message () from /lib64/libc.so.6 + #3 0x00007ffff73bdd7c in malloc_printerr () from /lib64/libc.so.6 + #4 0x00007ffff73c2f1a in realloc () from /lib64/libc.so.6 + #5 0x00007ffff78b558e in rfbSendOneRectEncodingZlib (cl=0x4a4b80, x=0, y=0, w=800, h=40) at /home/jonas/Dev/gnome/libvncserver/libvncserver/zlib.c:106 + #6 0x00007ffff78b5dec in rfbSendRectEncodingZlib (cl=0x4a4b80, x=0, y=0, w=800, h=600) at /home/jonas/Dev/gnome/libvncserver/libvncserver/zlib.c:308 + #7 0x00007ffff7899453 in rfbSendFramebufferUpdate (cl=0x4a4b80, givenUpdateRegion=0x49ef70) at /home/jonas/Dev/gnome/libvncserver/libvncserver/rfbserver.c:3264 + #8 0x00007ffff789079d in rfbUpdateClient (cl=0x4a4b80) at /home/jonas/Dev/gnome/libvncserver/libvncserver/main.c:1275 + #9 0x00007ffff78905f5 in rfbProcessEvents (screen=0x4d5790, usec=0) at /home/jonas/Dev/gnome/libvncserver/libvncserver/main.c:1251 +--- + libvncserver/zlib.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libvncserver/zlib.c b/libvncserver/zlib.c +index d24d7d15..5c3a8236 100644 +--- a/libvncserver/zlib.c ++++ b/libvncserver/zlib.c +@@ -64,11 +64,13 @@ void rfbZlibCleanup(rfbScreenInfoPtr screen) + { + if (zlibBeforeBufSize) { + free(zlibBeforeBuf); ++ zlibBeforeBuf = NULL; + zlibBeforeBufSize=0; + } + if (zlibAfterBufSize) { + zlibAfterBufSize=0; + free(zlibAfterBuf); ++ zlibAfterBuf = NULL; + } + } + +-- +2.28.0 + diff --git a/SOURCES/libvncserver-LibVNCServer-0.9.13-system-crypto-policy.patch b/SOURCES/libvncserver-LibVNCServer-0.9.13-system-crypto-policy.patch new file mode 100644 index 0000000..493617f --- /dev/null +++ b/SOURCES/libvncserver-LibVNCServer-0.9.13-system-crypto-policy.patch @@ -0,0 +1,15 @@ +diff -up libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c.crypto_policy libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c +--- libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c.crypto_policy 2020-06-13 13:49:53.000000000 -0500 ++++ libvncserver-LibVNCServer-0.9.13/libvncclient/tls_gnutls.c 2020-07-02 08:00:54.304902893 -0500 +@@ -29,8 +29,8 @@ + #include "tls.h" + + +-static const char *rfbTLSPriority = "NORMAL:+DHE-DSS:+RSA:+DHE-RSA:+SRP"; +-static const char *rfbAnonTLSPriority= "NORMAL:+ANON-DH"; ++static const char *rfbTLSPriority = "@SYSTEM"; ++static const char *rfbAnonTLSPriority= "@SYSTEM:+ANON-DH"; + + #define DH_BITS 1024 + static gnutls_dh_params_t rfbDHParams; +diff -up libvncserver-LibVNCServer-0.9.13/libvncserver/rfbssl_gnutls.c.crypto_policy libvncserver-LibVNCServer-0.9.13/libvncserver/rfbssl_gnutls.c diff --git a/SPECS/libvncserver.spec b/SPECS/libvncserver.spec new file mode 100644 index 0000000..1fa02ef --- /dev/null +++ b/SPECS/libvncserver.spec @@ -0,0 +1,309 @@ +%undefine __cmake_in_source_build + +Summary: Library to make writing a VNC server easy +Name: libvncserver +Version: 0.9.13 +Release: 12%{?dist} + +# NOTE: --with-filetransfer => GPLv2 +License: GPLv2+ +URL: http://libvnc.github.io/ +Source0: https://github.com/LibVNC/libvncserver/archive/LibVNCServer-%{version}.tar.gz + +## TLS security type enablement patches +# https://github.com/LibVNC/libvncserver/pull/234 +Patch10: 0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch +Patch11: 0002-libvncserver-Add-channel-security-handlers.patch +# https://github.com/LibVNC/libvncserver/commit/87c52ee0551b7c4e76855d270d475b9e3039fe08 +Patch12: 0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch +# Fix crash on all runs after the first +# https://github.com/LibVNC/libvncserver/pull/444 +# https://bugzilla.redhat.com/show_bug.cgi?id=1882718 +Patch13: 0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch +# Fix another crasher +# https://gitlab.gnome.org/GNOME/gnome-remote-desktop/-/issues/45 +# https://bugzilla.redhat.com/show_bug.cgi?id=1882718 +Patch14: 0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch + +## downstream patches +Patch102: libvncserver-LibVNCServer-0.9.13-system-crypto-policy.patch + +BuildRequires: gcc-c++ +BuildRequires: cmake3 +BuildRequires: pkgconfig(gnutls) +BuildRequires: pkgconfig(sdl2) +BuildRequires: pkgconfig(libsystemd) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xdamage) +BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(xrandr) +BuildRequires: pkgconfig(xtst) +BuildRequires: pkgconfig(xinerama) +BuildRequires: pkgconfig(xfixes) +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(zlib) +BuildRequires: pkgconfig(libjpeg) +BuildRequires: pkgconfig(libpng) +#BuildRequires: pkgconfig(lzo2) +#BuildRequires: ffmpeg-devel +BuildRequires: gettext-devel +BuildRequires: libgcrypt-devel + + +BuildRequires: lzo-devel +BuildRequires: lzo-minilzo +BuildRequires: pkgconfig(libcrypto) +BuildRequires: pkgconfig(libssl) +# Additional deps for --with-x11vnc, see https://bugzilla.redhat.com/show_bug.cgi?id=864947 +BuildRequires: pkgconfig(avahi-client) +BuildRequires: pkgconfig(ice) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xdamage) +BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(xfixes) +BuildRequires: pkgconfig(xi) +BuildRequires: pkgconfig(xinerama) +BuildRequires: pkgconfig(xrandr) +BuildRequires: pkgconfig(xtst) + +# For %%check +BuildRequires: xorg-x11-xauth +BuildRequires: zlib-devel + +%description +LibVNCServer makes writing a VNC server (or more correctly, a program exporting +a frame-buffer via the Remote Frame Buffer protocol) easy. + +It hides the programmer from the tedious task of managing clients and +compression schemata. + +%package devel +Summary: Development files for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} +# libvncserver-config deps +Requires: coreutils +# /usr/include/rfb/rfbproto.h:#include +Requires: zlib-devel + +%description devel +The %{name}-devel package contains libraries and header files for +developing applications that use %{name}. + + +%prep +%setup -q -n %{name}-LibVNCServer-%{version} + +%patch10 -p1 -b .tls-1 +%patch11 -p1 -b .tls-2 +%patch12 -p1 -b .handlers +%patch13 -p1 -b .pointers +%patch14 -p1 -b .cursor_null + +%patch102 -p1 -b .crypto_policy + +# Nuke bundled minilzo +rm -fv common/lzodefs.h common/lzoconf.h commmon/minilzo.h common/minilzo.c + + +# Fix encoding +for file in ChangeLog ; do + mv ${file} ${file}.OLD && \ + iconv -f ISO_8859-1 -t UTF8 ${file}.OLD > ${file} && \ + touch --reference ${file}.OLD $file +done + + +%build +%cmake3 + +%cmake_build + + +%install +%cmake_install + + +%ldconfig_scriptlets + +%files +%license COPYING +%doc AUTHORS ChangeLog NEWS* README* TODO* +%{_libdir}/libvncclient.so.1 +%{_libdir}/libvncclient.so.%{version} +%{_libdir}/libvncserver.so.1 +%{_libdir}/libvncserver.so.%{version} + +%files devel +#{_bindir}/libvncserver-config +%{_includedir}/rfb/ +%{_libdir}/libvncclient.so +%{_libdir}/libvncserver.so +%{_libdir}/pkgconfig/libvncclient.pc +%{_libdir}/pkgconfig/libvncserver.pc + + +%changelog +* Thu Jan 20 2022 Fedora Release Engineering - 0.9.13-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Thu Jul 22 2021 Fedora Release Engineering - 0.9.13-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Tue Jan 26 2021 Fedora Release Engineering - 0.9.13-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Oct 12 2020 Adam Williamson - 0.9.13-9 +- Backport another crasher fix (#1882718) + +* Fri Oct 09 2020 Adam Williamson - 0.9.13-8 +- Rebase all patches so Patch12 applies +- Backport PR #444 to fix crash on all runs after the first (#1882718) + +* Mon Sep 14 2020 Jonas Ådahl - 0.9.13-7 +- Add API to unregister security handlers + +* Tue Aug 25 2020 Rex Dieter - 0.9.13-6 +- -devel: +Requires: zlib-devel + +* Mon Aug 03 2020 Rex Dieter - 0.9.13-5 +- use new cmake macros + +* Sat Aug 01 2020 Fedora Release Engineering - 0.9.13-4 +- Second attempt - Rebuilt for + https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Tue Jul 28 2020 Fedora Release Engineering - 0.9.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu Jul 02 2020 Rex Dieter - 0.9.13-2 +- tls patches rebased + +* Thu Jul 02 2020 Rex Dieter - 0.9.13-1 +- 0.9.13 +- FIXME/TODO: tls patches need rebasing, work-in-progress + +* Tue Feb 11 2020 Sérgio Basto - 0.9.12-1 +- Update to 0.9.12 + +* Wed Jan 29 2020 Fedora Release Engineering - 0.9.11-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jul 25 2019 Fedora Release Engineering - 0.9.11-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 0.9.11-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Fri Jul 13 2018 Fedora Release Engineering - 0.9.11-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Tue Jun 19 2018 Jonas Ådahl - 0.9.11-7 +- Add API to enable implementing TLS security type + +* Mon Feb 26 2018 Petr Pisar - 0.9.11-6 +- Fix CVE-2018-7225 (bug #1546860) + +* Wed Feb 07 2018 Fedora Release Engineering - 0.9.11-5.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 0.9.11-4.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 0.9.11-3.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Wed May 17 2017 Rex Dieter - 0.9.11-2.1 +- revert soname bump for < f26 + +* Tue May 16 2017 Rex Dieter - 0.9.11-2 +- libvncclient sets +SRP in priority string (#1449605) +- libvncserver blocks gtk-vnc clients >= 0.7.0 (#1451321) + +* Tue Feb 14 2017 Rex Dieter - 0.9.11-1 +- 0.9.11 (#1421948) + +* Fri Feb 10 2017 Fedora Release Engineering - 0.9.10-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Feb 18 2016 Than Ngo - 0.9.10-5 +- fix conflict with max() macro with gcc6, which causes build failure in KDE/Qt + like krfb + +* Thu Feb 04 2016 Fedora Release Engineering - 0.9.10-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Thu Dec 17 2015 Simone Caronni - 0.9.10-3 +- Update crypto policies patch. + +* Sat Dec 12 2015 Simone Caronni - 0.9.10-2 +- Add patch for using system crypto policies (#1179318). + +* Fri Dec 11 2015 Simone Caronni - 0.9.10-1 +- Update to official 0.9.10 release, update configure parameters and remove + upstreamed patches. +- Trim changelog. +- Clean up SPEC file. +- Add license macro. +- Remove very old obsolete/provides on pacakge with camel case (LibVNCServer). + +* Wed Jun 17 2015 Fedora Release Engineering - 0.9.10-0.7.20140718git9453be42 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu Sep 25 2014 Rex Dieter 0.9.10-0.6.20140718git9453be42 +- Security fixes (#1145878) ... +- CVE-2014-6051 (#1144287) +- CVE-2014-6052 (#1144288) +- CVE-2014-6053 (#1144289) +- CVE-2014-6054 (#1144291) +- CVE-2014-6055 (#1144293) + +* Sun Aug 17 2014 Fedora Release Engineering - 0.9.10-0.5.20140718git9453be42 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Aug 03 2014 Rex Dieter 0.9.10-0.4.20140718git9453be42 +- 20140718git9453be42 snapshot + +* Sun Aug 03 2014 Rex Dieter 0.9.10-0.3.20140405git646f844f +- include krfb patches (upstream pull request #16) + +* Sat Jun 07 2014 Fedora Release Engineering - 0.9.10-0.2.20140405git646f844f +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue Apr 29 2014 Rex Dieter 0.9.10-0.1.20140405git646f844f +- Update to the latest git commit 646f844 (#1092245) + +* Mon Mar 31 2014 Rex Dieter 0.9.9-11 +- x11vnc crash when client connect (#972618) + pull in some upstream commits that may help + +* Sat Dec 21 2013 Rex Dieter - 0.9.9-10 +- include additional dependencies for x11vnc (#864947) +- %%build: --disable-silent-rules +- cleanup spec, drop support for old rpm (el5) + +* Sat Aug 03 2013 Fedora Release Engineering - 0.9.9-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 23 2013 Rex Dieter 0.9.9-8 +- Automagic dependencies, explitictly build --with-gcrypt --with-png (#852660) + +* Thu Feb 14 2013 Rex Dieter 0.9.9-7 +- pkgconfig love (#854111) + +* Thu Feb 14 2013 Fedora Release Engineering - 0.9.9-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Jan 18 2013 Adam Tkac - 0.9.9-5 +- rebuild due to "jpeg8-ABI" feature drop + +* Fri Dec 21 2012 Adam Tkac - 0.9.9-4 +- rebuild against new libjpeg + +* Thu Jul 26 2012 Rex Dieter 0.9.9-3 +- libvncserver fails to build in mock with selinux enabled (#843603) + +* Thu Jul 19 2012 Fedora Release Engineering - 0.9.9-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon May 07 2012 Rex Dieter 0.9.9-1 +- 0.9.9