Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package LibVNCServer for openSUSE:Factory 
checked in at 2021-01-18 11:26:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/LibVNCServer (Old)
 and      /work/SRC/openSUSE:Factory/.LibVNCServer.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "LibVNCServer"

Mon Jan 18 11:26:13 2021 rev:44 rq:862815 version:0.9.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/LibVNCServer/LibVNCServer.changes        
2020-07-01 18:22:09.673851281 +0200
+++ /work/SRC/openSUSE:Factory/.LibVNCServer.new.28504/LibVNCServer.changes     
2021-01-18 11:26:20.064414591 +0100
@@ -1,0 +2,14 @@
+Fri Jan  8 15:07:43 UTC 2021 - Frederic Crozat <fcro...@suse.com>
+
+- Add many patches needed for GNOME Remote desktop (already in
+  Fedora):
+  * TLS security type enablement patches gh#LibVNC/libvncserver!234 
+    - 0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch
+    - 0002-libvncserver-Add-channel-security-handlers.patch
+    - 0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch
+  * Fix crash on all runs after the first gh#LibVNC/libvncserver!444 rh#1882718
+    - 0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch
+  * Fix another crasher glgo#GNOME/gnome-remote-desktop#45 rh#1882718
+    - 0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch
+
+-------------------------------------------------------------------

New:
----
  0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch
  0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch
  0002-libvncserver-Add-channel-security-handlers.patch
  0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch
  0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ LibVNCServer.spec ++++++
--- /var/tmp/diff_new_pack.u5vdo4/_old  2021-01-18 11:26:20.892416456 +0100
+++ /var/tmp/diff_new_pack.u5vdo4/_new  2021-01-18 11:26:20.896416464 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package LibVNCServer
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -29,6 +29,15 @@
 Source1:        baselibs.conf
 #PATCH-FIX-OPENSUSE: redefine keysyms only if needed
 Patch0:         redef-keysym.patch
+#PATCH-FEATURE-UPSTREAM TLS security type enablement patches 
gh#LibVNC/libvncserver!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
+# PATCH-FIX-UPSTREAM Fix crash on all runs after the first 
gh#LibVNC/libvncserver!444 rh#1882718
+Patch13:        0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch
+# PATCH-FIX-UPSTREAM Fix another crasher glgo#GNOME/gnome-remote-desktop#45 
rh#1882718
+Patch14:        0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch
 BuildRequires:  cmake
 BuildRequires:  gcc-c++
 BuildRequires:  libavahi-devel
@@ -95,7 +104,8 @@
 
 %prep
 %setup -q -n libvncserver-%{name}-%{version}
-%patch0 -p1
+%autopatch -p1
+
 # fix encoding
 for file in ChangeLog ; do
 mv ${file} ${file}.OLD && \

++++++ 0001-libvncserver-Add-API-to-add-custom-I-O-entry-points.patch ++++++
>From e4849b01fec4494057728d1aa3a165ed21705682 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jad...@gmail.com>
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)
+{
+    return 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

++++++ 0001-libvncserver-don-t-NULL-out-internal-of-the-default-.patch ++++++
>From d138cf90130b0e8d5062f136ecdbcaa85e734d5d Mon Sep 17 00:00:00 2001
From: Christian Beier <i...@christianbeier.net>
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

++++++ 0002-libvncserver-Add-channel-security-handlers.patch ++++++
>From c9131a78878a785c3de21e9d49521d7b68400ad7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jad...@gmail.com>
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 && size<MAX_SECURITY_TYPES; handler = handler->next) {
+       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 && size<MAX_SECURITY_TYPES; handler = handler->next) {
+       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

++++++ 0003-libvncserver-auth-don-t-keep-security-handlers-from-.patch ++++++
>From 2a77dd86a97fa5f4735f678599cea839ba09009c Mon Sep 17 00:00:00 2001
From: Christian Beier <i...@christianbeier.net>
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

++++++ 0004-zlib-Clear-buffer-pointers-on-cleanup-444.patch ++++++
>From 641610b961a732bb68f111536ebf8c42be20f05b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jad...@gmail.com>
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

Reply via email to