diff --git a/.gitignore b/.gitignore index bcdfabc..473d203 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/tigervnc-1.9.0.tar.gz +SOURCES/tigervnc-1.10.1.tar.gz diff --git a/.tigervnc.metadata b/.tigervnc.metadata index 60dae98..957f8a1 100644 --- a/.tigervnc.metadata +++ b/.tigervnc.metadata @@ -1 +1 @@ -c56656c596fb863bb2c4b67fb62b4165011d181f SOURCES/tigervnc-1.9.0.tar.gz +34efc6e2e67be672dca38c10ce064bcb08adee9f SOURCES/tigervnc-1.10.1.tar.gz diff --git a/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch b/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch new file mode 100644 index 0000000..b67127b --- /dev/null +++ b/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch @@ -0,0 +1,34 @@ +From 920d9c4d6562ecabf79497bc901d50522d4bc661 Mon Sep 17 00:00:00 2001 +From: Linus Heckemann +Date: Sat, 1 Feb 2020 11:08:26 +0100 +Subject: [PATCH] xserver: add no-op input thread init function + +This allows Xvnc to build with xorg-server 1.20.7, which requires OS +layers to implement a ddxInputThreadInit function when configured with +--enable-input-thread (the default). + +relevant xorg-server commit: e3f26605d85d987da434640f52646d728f1fe919 +--- + unix/xserver/hw/vnc/Input.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c +index 534e435e..b342d4d6 100644 +--- a/unix/xserver/hw/vnc/Input.c ++++ b/unix/xserver/hw/vnc/Input.c +@@ -711,3 +711,12 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) + */ + mieqProcessInputEvents(); + } ++ ++#if INPUTTHREAD ++/** This function is called in Xserver/os/inputthread.c when starting ++ the input thread. */ ++void ++ddxInputThreadInit(void) ++{ ++} ++#endif +-- +2.24.1 + diff --git a/SOURCES/HOWTO.md b/SOURCES/HOWTO.md new file mode 100644 index 0000000..28b710d --- /dev/null +++ b/SOURCES/HOWTO.md @@ -0,0 +1,110 @@ +# What has changed +The previous Tigervnc versions had a wrapper script called `vncserver` which +could be run as a user manually to start *Xvnc* process. The usage was quite +simple as you just run +``` +$ vncserver :x [vncserver options] [Xvnc options] +``` +and that was it. While this was working just fine, there were issues when users +wanted to start a Tigervnc server using *systemd*. For these reasons things were +completely changed and there is now a new way how this all is supposed to work. + + # How to start Tigervnc server +  +## Add a user mapping +With this you can map a user to a particular port. The mapping should be done in +`/etc/tigervnc/vncserver.users` configuration file. It should be pretty +straightforward once you open the file as there are some examples, but basically +the mapping is in form +``` +:x=user +``` +For example you can have +``` +:1=test +:2=vncuser +``` + +## Configure Xvnc options +To configure Xvnc parameters, you need to go to the same directory where you did +the user mapping and open `vncserver-config-defaults` configuration file. This +file is for the default Xvnc configuration and will be applied to every user +unless any of the following applies: +* The user has its own configuration in `$HOME/.vnc/config` +* The same option with different value is configured in +  `vncserver-config-mandatory` configuration file, which replaces the default +  configuration and has even a higher priority than the per-user configuration. +  This option is for system administrators when they want to force particular +  *Xvnc* options. + +Format of the configuration file is also quite simple as the configuration is +in form of +``` +option=value +option +``` +for example +``` +session=gnome +securitytypes=vncauth,tlsvnc +desktop=sandbox +geometry=2000x1200 +localhost +alwaysshared +``` +### Note: +There is one important option you need to set and that option is the session you +want to start. E.g when you want to start GNOME desktop, then you have to use +``` +session=gnome +``` +which should match the name of a session desktop file from `/usr/share/xsessions` +directory. + +## Set VNC password +You need to set a password for each user in order to be able to start the +Tigervnc server. In order to create a password, you just run +``` +$ vncpasswd +``` +as the user you will be starting the server for. +### Note: +If you were using Tigervnc before for your user and you already created a +password, then you will have to make sure the `$HOME/.vnc` folder created by +`vncpasswd` will have the correct *SELinux* context. You either can delete this +folder and recreate it again by creating the password one more time, or +alternatively you can run +``` +$ restorecon -RFv /home//.vnc +``` + +## Start the Tigervnc server +Finally you can start the server using systemd service. To do so just run +``` +$ systemctl start vncserver@:x +``` +as root or +``` +$ sudo systemctl start vncserver@:x +``` +as a regular user in case it has permissions to run `sudo`. Don't forget to +replace the `:x` by the actual number you configured in the user mapping file. +Following our example by running +``` +$ systemctl start vncserver@:1 +``` +you will start a Tigervnc server for user `test` with a GNOME session. + +### Note: +If you were previously using Tigervnc and you were used to start it using +*systemd* then you will need to remove previous *systemd* configuration files, +those you most likely copied to `/etc/systemd/system/vncserver@.service`, +otherwise this service file will be preferred over the new one installed with +latest Tigervnc. + +# Limitations +You will not be able to start a Tigervnc server for a user who is already +logged into a graphical session. Avoid running the server as the `root` user as +it's not a safe thing to do. While running the server as the `root` should work +in general, it's not recommended to do so and there might be some things which +are not working properly. diff --git a/SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch b/SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch deleted file mode 100644 index 3623b14..0000000 --- a/SOURCES/tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/unix/vncserver b/unix/vncserver -index a6c890f..687ef72 100755 ---- a/unix/vncserver -+++ b/unix/vncserver -@@ -208,7 +208,8 @@ if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) { - $displayNumber = $1; - shift(@ARGV); - if (!&CheckDisplayNumber($displayNumber)) { -- die "A VNC server is already running as :$displayNumber\n"; -+ warn "A VNC server is already running as :$displayNumber\n"; -+ $displayNumber = &GetDisplayNumber(); - } - } elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) { - &Usage(); diff --git a/SOURCES/tigervnc-CVE-2019-15691.patch b/SOURCES/tigervnc-CVE-2019-15691.patch deleted file mode 100644 index 1b0a6c8..0000000 --- a/SOURCES/tigervnc-CVE-2019-15691.patch +++ /dev/null @@ -1,116 +0,0 @@ -From d61a767d6842b530ffb532ddd5a3d233119aad40 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Tue, 10 Sep 2019 11:05:48 +0200 -Subject: [PATCH] Make ZlibInStream more robust against failures - -Move the checks around to avoid missing cases where we might access -memory that is no longer valid. Also avoid touching the underlying -stream implicitly (e.g. via the destructor) as it might also no -longer be valid. - -A malicious server could theoretically use this for remote code -execution in the client. - -Issue found by Pavel Cheremushkin from Kaspersky Lab ---- - common/rdr/ZlibInStream.cxx | 13 +++++++------ - common/rdr/ZlibInStream.h | 2 +- - common/rfb/CMsgReader.cxx | 3 ++- - common/rfb/SMsgReader.cxx | 3 ++- - common/rfb/TightDecoder.cxx | 3 ++- - common/rfb/zrleDecode.h | 3 ++- - 6 files changed, 16 insertions(+), 11 deletions(-) - -diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx -index 4053bd1..a361010 100644 ---- a/common/rdr/ZlibInStream.cxx -+++ b/common/rdr/ZlibInStream.cxx -@@ -52,16 +52,16 @@ int ZlibInStream::pos() - return offset + ptr - start; - } - --void ZlibInStream::removeUnderlying() -+void ZlibInStream::flushUnderlying() - { - ptr = end = start; -- if (!underlying) return; - - while (bytesIn > 0) { - decompress(true); - end = start; // throw away any data - } -- underlying = 0; -+ -+ setUnderlying(NULL, 0); - } - - void ZlibInStream::reset() -@@ -90,7 +90,7 @@ void ZlibInStream::init() - void ZlibInStream::deinit() - { - assert(zs != NULL); -- removeUnderlying(); -+ setUnderlying(NULL, 0); - inflateEnd(zs); - delete zs; - zs = NULL; -@@ -100,8 +100,6 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait) - { - if (itemSize > bufSize) - throw Exception("ZlibInStream overrun: max itemSize exceeded"); -- if (!underlying) -- throw Exception("ZlibInStream overrun: no underlying stream"); - - if (end - ptr != 0) - memmove(start, ptr, end - ptr); -@@ -127,6 +125,9 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait) - - bool ZlibInStream::decompress(bool wait) - { -+ if (!underlying) -+ throw Exception("ZlibInStream overrun: no underlying stream"); -+ - zs->next_out = (U8*)end; - zs->avail_out = start + bufSize - end; - -diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h -index 6bd4da4..86ba1ff 100644 ---- a/common/rdr/ZlibInStream.h -+++ b/common/rdr/ZlibInStream.h -@@ -38,7 +38,7 @@ namespace rdr { - virtual ~ZlibInStream(); - - void setUnderlying(InStream* is, int bytesIn); -- void removeUnderlying(); -+ void flushUnderlying(); - int pos(); - void reset(); - -diff --git a/common/rfb/TightDecoder.cxx b/common/rfb/TightDecoder.cxx -index 3a1254a..4273eb7 100644 ---- a/common/rfb/TightDecoder.cxx -+++ b/common/rfb/TightDecoder.cxx -@@ -340,7 +340,8 @@ void TightDecoder::decodeRect(const Rect& r, const void* buffer, - - zis[streamId].readBytes(netbuf, dataSize); - -- zis[streamId].removeUnderlying(); -+ zis[streamId].flushUnderlying(); -+ zis[streamId].setUnderlying(NULL, 0); - delete ms; - - bufptr = netbuf; -diff --git a/common/rfb/zrleDecode.h b/common/rfb/zrleDecode.h -index 0bfbbe1..a69ca67 100644 ---- a/common/rfb/zrleDecode.h -+++ b/common/rfb/zrleDecode.h -@@ -178,7 +178,8 @@ void ZRLE_DECODE (const Rect& r, rdr::InStream* is, - } - } - -- zis->removeUnderlying(); -+ zis->flushUnderlying(); -+ zis->setUnderlying(NULL, 0); - } - - #undef ZRLE_DECODE diff --git a/SOURCES/tigervnc-CVE-2019-15692.patch b/SOURCES/tigervnc-CVE-2019-15692.patch deleted file mode 100644 index 4b0e983..0000000 --- a/SOURCES/tigervnc-CVE-2019-15692.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 996356b6c65ca165ee1ea46a571c32a1dc3c3821 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Tue, 10 Sep 2019 15:21:03 +0200 -Subject: [PATCH] Restrict PixelBuffer dimensions to safe values - -We do a lot of calculations based on pixel coordinates and we need -to make sure they do not overflow. Restrict the maximum dimensions -we support rather than try to switch over all calculations to use -64 bit integers. - -This prevents attackers from from injecting code by specifying a -huge framebuffer size and relying on the values overflowing to -access invalid areas of the heap. - -This primarily affects the client which gets both the screen -dimensions and the pixel contents from the remote side. But the -server might also be affected as a client can adjust the screen -dimensions, as can applications inside the session. - -Issue found by Pavel Cheremushkin from Kaspersky Lab. ---- - common/rfb/PixelBuffer.cxx | 22 ++++++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx -index ad58324..18f41f8 100644 ---- a/common/rfb/PixelBuffer.cxx -+++ b/common/rfb/PixelBuffer.cxx -@@ -31,6 +31,14 @@ using namespace rdr; - - static LogWriter vlog("PixelBuffer"); - -+// We do a lot of byte offset calculations that assume the result fits -+// inside a signed 32 bit integer. Limit the maximum size of pixel -+// buffers so that these calculations never overflow. -+ -+const int maxPixelBufferWidth = 16384; -+const int maxPixelBufferHeight = 16384; -+const int maxPixelBufferStride = 16384; -+ - - // -=- Generic pixel buffer class - -@@ -108,6 +116,11 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf, - - void PixelBuffer::setSize(int width, int height) - { -+ if ((width < 0) || (width > maxPixelBufferWidth)) -+ throw rfb::Exception("Invalid PixelBuffer width of %d pixels requested", width); -+ if ((height < 0) || (height > maxPixelBufferHeight)) -+ throw rfb::Exception("Invalid PixelBuffer height of %d pixels requested", height); -+ - width_ = width; - height_ = height; - } -@@ -337,6 +350,15 @@ const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) cons - void FullFramePixelBuffer::setBuffer(int width, int height, - rdr::U8* data_, int stride_) - { -+ if ((width < 0) || (width > maxPixelBufferWidth)) -+ throw rfb::Exception("Invalid PixelBuffer width of %d pixels requested", width); -+ if ((height < 0) || (height > maxPixelBufferHeight)) -+ throw rfb::Exception("Invalid PixelBuffer height of %d pixels requested", height); -+ if ((stride_ < 0) || (stride_ > maxPixelBufferStride) || (stride_ < width)) -+ throw rfb::Exception("Invalid PixelBuffer stride of %d pixels requested", stride_); -+ if ((width != 0) && (height != 0) && (data_ == NULL)) -+ throw rfb::Exception("PixelBuffer requested without a valid memory area"); -+ - ModifiablePixelBuffer::setSize(width, height); - stride = stride_; - data = data_; diff --git a/SOURCES/tigervnc-CVE-2019-15693.patch b/SOURCES/tigervnc-CVE-2019-15693.patch deleted file mode 100644 index 1e5f152..0000000 --- a/SOURCES/tigervnc-CVE-2019-15693.patch +++ /dev/null @@ -1,75 +0,0 @@ -From b4ada8d0c6dac98c8b91fc64d112569a8ae5fb95 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Tue, 10 Sep 2019 15:36:42 +0200 -Subject: [PATCH] Handle empty Tight gradient rects - -We always assumed there would be one pixel per row so a rect with -a zero width would result in us writing to unknown memory. - -This could theoretically be used by a malicious server to inject -code in to the viewer process. - -Issue found by Pavel Cheremushkin from Kaspersky Lab. ---- - common/rfb/tightDecode.h | 37 +++++++++++++++++++++---------------- - 1 file changed, 21 insertions(+), 16 deletions(-) - -diff --git a/common/rfb/tightDecode.h b/common/rfb/tightDecode.h -index b6e86ed5e..8f77aebd0 100644 ---- a/common/rfb/tightDecode.h -+++ b/common/rfb/tightDecode.h -@@ -56,15 +56,17 @@ TightDecoder::FilterGradient24(const rdr::U8 *inbuf, - int rectWidth = r.width(); - - for (y = 0; y < rectHeight; y++) { -- /* First pixel in a row */ -- for (c = 0; c < 3; c++) { -- pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c]; -- thisRow[c] = pix[c]; -- } -- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); -+ for (x = 0; x < rectWidth; x++) { -+ /* First pixel in a row */ -+ if (x == 0) { -+ for (c = 0; c < 3; c++) { -+ pix[c] = inbuf[y*rectWidth*3+c] + prevRow[c]; -+ thisRow[c] = pix[c]; -+ } -+ pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); -+ continue; -+ } - -- /* Remaining pixels of a row */ -- for (x = 1; x < rectWidth; x++) { - for (c = 0; c < 3; c++) { - est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]; - if (est[c] > 0xff) { -@@ -103,17 +105,20 @@ void TightDecoder::FilterGradient(const rdr::U8* inbuf, - int rectWidth = r.width(); - - for (y = 0; y < rectHeight; y++) { -- /* First pixel in a row */ -- pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1); -- for (c = 0; c < 3; c++) -- pix[c] += prevRow[c]; -+ for (x = 0; x < rectWidth; x++) { -+ /* First pixel in a row */ -+ if (x == 0) { -+ pf.rgbFromBuffer(pix, &inbuf[y*rectWidth], 1); -+ for (c = 0; c < 3; c++) -+ pix[c] += prevRow[c]; - -- memcpy(thisRow, pix, sizeof(pix)); -+ memcpy(thisRow, pix, sizeof(pix)); - -- pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); -+ pf.bufferFromRGB((rdr::U8*)&outbuf[y*stride], pix, 1); -+ -+ continue; -+ } - -- /* Remaining pixels of a row */ -- for (x = 1; x < rectWidth; x++) { - for (c = 0; c < 3; c++) { - est[c] = prevRow[x*3+c] + pix[c] - prevRow[(x-1)*3+c]; - if (est[c] > 255) { diff --git a/SOURCES/tigervnc-CVE-2019-15694.patch b/SOURCES/tigervnc-CVE-2019-15694.patch deleted file mode 100644 index 8f3fc27..0000000 --- a/SOURCES/tigervnc-CVE-2019-15694.patch +++ /dev/null @@ -1,1419 +0,0 @@ -From 0943c006c7d900dfc0281639e992791d6c567438 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Mon, 23 Sep 2019 11:00:17 +0200 -Subject: [PATCH] Use size_t for lengths in stream objects - -Provides safety against them accidentally becoming negative because -of bugs in the calculations. - -Also does the same to CharArray and friends as they were strongly -connection to the stream objects. ---- - common/rdr/FdInStream.cxx | 20 ++++++++++---------- - common/rdr/FdInStream.h | 17 +++++++++-------- - common/rdr/FdOutStream.cxx | 20 ++++++++++---------- - common/rdr/FdOutStream.h | 12 ++++++------ - common/rdr/FileInStream.cxx | 8 ++++---- - common/rdr/FileInStream.h | 4 ++-- - common/rdr/HexInStream.cxx | 20 ++++++++++---------- - common/rdr/HexInStream.h | 12 ++++++------ - common/rdr/HexOutStream.cxx | 20 ++++++++++---------- - common/rdr/HexOutStream.h | 12 ++++++------ - common/rdr/InStream.h | 16 ++++++++-------- - common/rdr/MemInStream.h | 8 ++++---- - common/rdr/MemOutStream.h | 12 ++++++------ - common/rdr/OutStream.h | 20 ++++++++++---------- - common/rdr/RandomStream.cxx | 14 +++++++------- - common/rdr/RandomStream.h | 6 +++--- - common/rdr/TLSInStream.cxx | 10 +++++----- - common/rdr/TLSInStream.h | 10 +++++----- - common/rdr/TLSOutStream.cxx | 10 +++++----- - common/rdr/TLSOutStream.h | 10 +++++----- - common/rdr/ZlibInStream.cxx | 16 ++++++++-------- - common/rdr/ZlibInStream.h | 14 +++++++------- - common/rdr/ZlibOutStream.cxx | 10 +++++----- - common/rdr/ZlibOutStream.h | 10 +++++----- - common/rfb/Configuration.cxx | 6 +++--- - common/rfb/Configuration.h | 13 +++++++------ - common/rfb/Password.cxx | 6 +++--- - common/rfb/Password.h | 6 +++--- - common/rfb/util.h | 2 +- - tests/perf/encperf.cxx | 10 +++++----- - win/rfb_win32/Registry.cxx | 6 +++--- - win/rfb_win32/Registry.h | 6 +++--- - 32 files changed, 184 insertions(+), 182 deletions(-) - -diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx -index 011ebf4..789cbec 100644 ---- a/common/rdr/FdInStream.cxx -+++ b/common/rdr/FdInStream.cxx -@@ -56,7 +56,7 @@ using namespace rdr; - enum { DEFAULT_BUF_SIZE = 8192, - MIN_BULK_SIZE = 1024 }; - --FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_, -+FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_, - bool closeWhenDone_) - : fd(fd_), closeWhenDone(closeWhenDone_), - timeoutms(timeoutms_), blockCallback(0), -@@ -67,7 +67,7 @@ FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_, - } - - FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_, -- int bufSize_) -+ size_t bufSize_) - : fd(fd_), timeoutms(0), blockCallback(blockCallback_), - timing(false), timeWaitedIn100us(5), timedKbits(0), - bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) -@@ -92,12 +92,12 @@ void FdInStream::setBlockCallback(FdInStreamBlockCallback* blockCallback_) - timeoutms = 0; - } - --int FdInStream::pos() -+size_t FdInStream::pos() - { - return offset + ptr - start; - } - --void FdInStream::readBytes(void* data, int length) -+void FdInStream::readBytes(void* data, size_t length) - { - if (length < MIN_BULK_SIZE) { - InStream::readBytes(data, length); -@@ -106,7 +106,7 @@ void FdInStream::readBytes(void* data, int length) - - U8* dataPtr = (U8*)data; - -- int n = end - ptr; -+ size_t n = end - ptr; - if (n > length) n = length; - - memcpy(dataPtr, ptr, n); -@@ -123,7 +123,7 @@ void FdInStream::readBytes(void* data, int length) - } - - --int FdInStream::overrun(int itemSize, int nItems, bool wait) -+size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait) - { - if (itemSize > bufSize) - throw Exception("FdInStream overrun: max itemSize exceeded"); -@@ -135,7 +135,7 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait) - end -= ptr - start; - ptr = start; - -- int bytes_to_read; -+ size_t bytes_to_read; - while (end < start + itemSize) { - bytes_to_read = start + bufSize - end; - if (!timing) { -@@ -147,12 +147,12 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait) - // bytes is ineffecient. - bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8)); - } -- int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait); -+ size_t n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait); - if (n == 0) return 0; - end += n; - } - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -@@ -171,7 +171,7 @@ int FdInStream::overrun(int itemSize, int nItems, bool wait) - // returning EINTR. - // - --int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait) -+size_t FdInStream::readWithTimeoutOrCallback(void* buf, size_t len, bool wait) - { - struct timeval before, after; - if (timing) -diff --git a/common/rdr/FdInStream.h b/common/rdr/FdInStream.h -index b4c8765..d99ad3c 100644 ---- a/common/rdr/FdInStream.h -+++ b/common/rdr/FdInStream.h -@@ -37,16 +37,17 @@ namespace rdr { - - public: - -- FdInStream(int fd, int timeoutms=-1, int bufSize=0, -+ FdInStream(int fd, int timeoutms=-1, size_t bufSize=0, - bool closeWhenDone_=false); -- FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0); -+ FdInStream(int fd, FdInStreamBlockCallback* blockCallback, -+ size_t bufSize=0); - virtual ~FdInStream(); - - void setTimeout(int timeoutms); - void setBlockCallback(FdInStreamBlockCallback* blockCallback); - int getFd() { return fd; } -- int pos(); -- void readBytes(void* data, int length); -+ size_t pos(); -+ void readBytes(void* data, size_t length); - - void startTiming(); - void stopTiming(); -@@ -54,10 +55,10 @@ namespace rdr { - unsigned int timeWaited() { return timeWaitedIn100us; } - - protected: -- int overrun(int itemSize, int nItems, bool wait); -+ size_t overrun(size_t itemSize, size_t nItems, bool wait); - - private: -- int readWithTimeoutOrCallback(void* buf, int len, bool wait=true); -+ size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true); - - int fd; - bool closeWhenDone; -@@ -68,8 +69,8 @@ namespace rdr { - unsigned int timeWaitedIn100us; - unsigned int timedKbits; - -- int bufSize; -- int offset; -+ size_t bufSize; -+ size_t offset; - U8* start; - }; - -diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx -index cf857f8..1757dc3 100644 ---- a/common/rdr/FdOutStream.cxx -+++ b/common/rdr/FdOutStream.cxx -@@ -51,7 +51,7 @@ using namespace rdr; - - enum { DEFAULT_BUF_SIZE = 16384 }; - --FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_) -+FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, size_t bufSize_) - : fd(fd_), blocking(blocking_), timeoutms(timeoutms_), - bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) - { -@@ -79,7 +79,7 @@ void FdOutStream::setBlocking(bool blocking_) { - blocking = blocking_; - } - --int FdOutStream::length() -+size_t FdOutStream::length() - { - return offset + ptr - sentUpTo; - } -@@ -97,9 +97,9 @@ unsigned FdOutStream::getIdleTime() - void FdOutStream::flush() - { - while (sentUpTo < ptr) { -- int n = writeWithTimeout((const void*) sentUpTo, -- ptr - sentUpTo, -- blocking? timeoutms : 0); -+ size_t n = writeWithTimeout((const void*) sentUpTo, -+ ptr - sentUpTo, -+ blocking? timeoutms : 0); - - // Timeout? - if (n == 0) { -@@ -120,7 +120,7 @@ void FdOutStream::flush() - } - - --int FdOutStream::overrun(int itemSize, int nItems) -+size_t FdOutStream::overrun(size_t itemSize, size_t nItems) - { - if (itemSize > bufSize) - throw Exception("FdOutStream overrun: max itemSize exceeded"); -@@ -129,10 +129,10 @@ int FdOutStream::overrun(int itemSize, int nItems) - flush(); - - // Still not enough space? -- if (itemSize > end - ptr) { -+ if (itemSize > (size_t)(end - ptr)) { - // Can we shuffle things around? - // (don't do this if it gains us less than 25%) -- if ((sentUpTo - start > bufSize / 4) && -+ if (((size_t)(sentUpTo - start) > bufSize / 4) && - (itemSize < bufSize - (ptr - sentUpTo))) { - memmove(start, sentUpTo, ptr - sentUpTo); - ptr = start + (ptr - sentUpTo); -@@ -150,7 +150,7 @@ int FdOutStream::overrun(int itemSize, int nItems) - } - - // Can we fit all the items asked for? -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -@@ -166,7 +166,7 @@ int FdOutStream::overrun(int itemSize, int nItems) - // select() and send() returning EINTR. - // - --int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms) -+size_t FdOutStream::writeWithTimeout(const void* data, size_t length, int timeoutms) - { - int n; - -diff --git a/common/rdr/FdOutStream.h b/common/rdr/FdOutStream.h -index b7f6cb0..ed84fdb 100644 ---- a/common/rdr/FdOutStream.h -+++ b/common/rdr/FdOutStream.h -@@ -34,7 +34,7 @@ namespace rdr { - - public: - -- FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0); -+ FdOutStream(int fd, bool blocking=true, int timeoutms=-1, size_t bufSize=0); - virtual ~FdOutStream(); - - void setTimeout(int timeoutms); -@@ -42,20 +42,20 @@ namespace rdr { - int getFd() { return fd; } - - void flush(); -- int length(); -+ size_t length(); - - int bufferUsage(); - - unsigned getIdleTime(); - - private: -- int overrun(int itemSize, int nItems); -- int writeWithTimeout(const void* data, int length, int timeoutms); -+ size_t overrun(size_t itemSize, size_t nItems); -+ size_t writeWithTimeout(const void* data, size_t length, int timeoutms); - int fd; - bool blocking; - int timeoutms; -- int bufSize; -- int offset; -+ size_t bufSize; -+ size_t offset; - U8* start; - U8* sentUpTo; - struct timeval lastWrite; -diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx -index 3acdfd4..94f5db8 100644 ---- a/common/rdr/FileInStream.cxx -+++ b/common/rdr/FileInStream.cxx -@@ -48,7 +48,7 @@ void FileInStream::reset(void) { - ptr = end = b; - } - --int FileInStream::pos() -+size_t FileInStream::pos() - { - if (!file) - throw Exception("File is not open"); -@@ -56,9 +56,9 @@ int FileInStream::pos() - return ftell(file) + ptr - b; - } - --int FileInStream::overrun(int itemSize, int nItems, bool wait) -+size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait) - { -- if (itemSize > (int)sizeof(b)) -+ if (itemSize > sizeof(b)) - throw Exception("FileInStream overrun: max itemSize exceeded"); - - if (end - ptr != 0) -@@ -80,7 +80,7 @@ int FileInStream::overrun(int itemSize, int nItems, bool wait) - end += b + sizeof(b) - end; - } - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -diff --git a/common/rdr/FileInStream.h b/common/rdr/FileInStream.h -index ace04f3..a33c765 100644 ---- a/common/rdr/FileInStream.h -+++ b/common/rdr/FileInStream.h -@@ -35,10 +35,10 @@ namespace rdr { - - void reset(void); - -- int pos(); -+ size_t pos(); - - protected: -- int overrun(int itemSize, int nItems, bool wait = true); -+ size_t overrun(size_t itemSize, size_t nItems, bool wait = true); - - private: - U8 b[131072]; -diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx -index 80f8a79..8f93988 100644 ---- a/common/rdr/HexInStream.cxx -+++ b/common/rdr/HexInStream.cxx -@@ -28,7 +28,7 @@ const int DEFAULT_BUF_LEN = 16384; - - static inline int min(int a, int b) {return a bufSize) - throw Exception("HexInStream overrun: max itemSize exceeded"); - -@@ -92,14 +92,14 @@ int HexInStream::overrun(int itemSize, int nItems, bool wait) { - ptr = start; - - while (end < ptr + itemSize) { -- int n = in_stream.check(2, 1, wait); -+ size_t n = in_stream.check(2, 1, wait); - if (n == 0) return 0; - const U8* iptr = in_stream.getptr(); - const U8* eptr = in_stream.getend(); -- int length = min((eptr - iptr)/2, start + bufSize - end); -+ size_t length = min((eptr - iptr)/2, start + bufSize - end); - - U8* optr = (U8*) end; -- for (int i=0; i end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -diff --git a/common/rdr/HexInStream.h b/common/rdr/HexInStream.h -index 6bfb843..8e495fb 100644 ---- a/common/rdr/HexInStream.h -+++ b/common/rdr/HexInStream.h -@@ -26,21 +26,21 @@ namespace rdr { - class HexInStream : public InStream { - public: - -- HexInStream(InStream& is, int bufSize=0); -+ HexInStream(InStream& is, size_t bufSize=0); - virtual ~HexInStream(); - -- int pos(); -+ size_t pos(); - - static bool readHexAndShift(char c, int* v); -- static bool hexStrToBin(const char* s, char** data, int* length); -+ static bool hexStrToBin(const char* s, char** data, size_t* length); - - protected: -- int overrun(int itemSize, int nItems, bool wait); -+ size_t overrun(size_t itemSize, size_t nItems, bool wait); - - private: -- int bufSize; -+ size_t bufSize; - U8* start; -- int offset; -+ size_t offset; - - InStream& in_stream; - }; -diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx -index 9b0b6c4..7232514 100644 ---- a/common/rdr/HexOutStream.cxx -+++ b/common/rdr/HexOutStream.cxx -@@ -23,9 +23,9 @@ using namespace rdr; - - const int DEFAULT_BUF_LEN = 16384; - --static inline int min(int a, int b) {return a> 4) & 15); - buffer[i*2+1] = intToHex((data[i] & 15)); - if (!buffer[i*2] || !buffer[i*2+1]) { -@@ -70,9 +70,9 @@ HexOutStream::writeBuffer() { - out_stream.check(2); - U8* optr = out_stream.getptr(); - U8* oend = out_stream.getend(); -- int length = min(ptr-pos, (oend-optr)/2); -+ size_t length = min(ptr-pos, (oend-optr)/2); - -- for (int i=0; i> 4) & 0xf); - optr[i*2+1] = intToHex(pos[i] & 0xf); - } -@@ -84,7 +84,7 @@ HexOutStream::writeBuffer() { - ptr = start; - } - --int HexOutStream::length() -+size_t HexOutStream::length() - { - return offset + ptr - start; - } -@@ -95,14 +95,14 @@ HexOutStream::flush() { - out_stream.flush(); - } - --int --HexOutStream::overrun(int itemSize, int nItems) { -+size_t -+HexOutStream::overrun(size_t itemSize, size_t nItems) { - if (itemSize > bufSize) - throw Exception("HexOutStream overrun: max itemSize exceeded"); - - writeBuffer(); - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -diff --git a/common/rdr/HexOutStream.h b/common/rdr/HexOutStream.h -index 10247e6..92442a7 100644 ---- a/common/rdr/HexOutStream.h -+++ b/common/rdr/HexOutStream.h -@@ -26,24 +26,24 @@ namespace rdr { - class HexOutStream : public OutStream { - public: - -- HexOutStream(OutStream& os, int buflen=0); -+ HexOutStream(OutStream& os, size_t buflen=0); - virtual ~HexOutStream(); - - void flush(); -- int length(); -+ size_t length(); - - static char intToHex(int i); -- static char* binToHexStr(const char* data, int length); -+ static char* binToHexStr(const char* data, size_t length); - - private: - void writeBuffer(); -- int overrun(int itemSize, int nItems); -+ size_t overrun(size_t itemSize, size_t nItems); - - OutStream& out_stream; - - U8* start; -- int offset; -- int bufSize; -+ size_t offset; -+ size_t bufSize; - }; - - } -diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h -index 212a2ec..14ecf09 100644 ---- a/common/rdr/InStream.h -+++ b/common/rdr/InStream.h -@@ -41,7 +41,7 @@ namespace rdr { - // for the bytes, zero is returned if the bytes are not immediately - // available. - -- inline int check(int itemSize, int nItems=1, bool wait=true) -+ inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true) - { - if (ptr + itemSize * nItems > end) { - if (ptr + itemSize > end) -@@ -56,7 +56,7 @@ namespace rdr { - // be read without blocking. It returns true if this is the case, false - // otherwise. The length must be "small" (less than the buffer size). - -- inline bool checkNoWait(int length) { return check(length, 1, false)!=0; } -+ inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; } - - // readU/SN() methods read unsigned and signed N-bit integers. - -@@ -82,9 +82,9 @@ namespace rdr { - - static U32 maxStringLength; - -- inline void skip(int bytes) { -+ inline void skip(size_t bytes) { - while (bytes > 0) { -- int n = check(1, bytes); -+ size_t n = check(1, bytes); - ptr += n; - bytes -= n; - } -@@ -92,11 +92,11 @@ namespace rdr { - - // readBytes() reads an exact number of bytes. - -- void readBytes(void* data, int length) { -+ void readBytes(void* data, size_t length) { - U8* dataPtr = (U8*)data; - U8* dataEnd = dataPtr + length; - while (dataPtr < dataEnd) { -- int n = check(1, dataEnd - dataPtr); -+ size_t n = check(1, dataEnd - dataPtr); - memcpy(dataPtr, ptr, n); - ptr += n; - dataPtr += n; -@@ -114,7 +114,7 @@ namespace rdr { - - // pos() returns the position in the stream. - -- virtual int pos() = 0; -+ virtual size_t pos() = 0; - - // getptr(), getend() and setptr() are "dirty" methods which allow you to - // manipulate the buffer directly. This is useful for a stream which is a -@@ -133,7 +133,7 @@ namespace rdr { - // instead of blocking to wait for the bytes, zero is returned if the bytes - // are not immediately available. - -- virtual int overrun(int itemSize, int nItems, bool wait=true) = 0; -+ virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0; - - protected: - -diff --git a/common/rdr/MemInStream.h b/common/rdr/MemInStream.h -index 1a6a798..3e9e77b 100644 ---- a/common/rdr/MemInStream.h -+++ b/common/rdr/MemInStream.h -@@ -36,7 +36,7 @@ namespace rdr { - - public: - -- MemInStream(const void* data, int len, bool deleteWhenDone_=false) -+ MemInStream(const void* data, size_t len, bool deleteWhenDone_=false) - : start((const U8*)data), deleteWhenDone(deleteWhenDone_) - { - ptr = start; -@@ -48,12 +48,12 @@ namespace rdr { - delete [] start; - } - -- int pos() { return ptr - start; } -- void reposition(int pos) { ptr = start + pos; } -+ size_t pos() { return ptr - start; } -+ void reposition(size_t pos) { ptr = start + pos; } - - private: - -- int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); } -+ size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); } - const U8* start; - bool deleteWhenDone; - }; -diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h -index 3b17e55..4a815b3 100644 ---- a/common/rdr/MemOutStream.h -+++ b/common/rdr/MemOutStream.h -@@ -40,16 +40,16 @@ namespace rdr { - delete [] start; - } - -- void writeBytes(const void* data, int length) { -+ void writeBytes(const void* data, size_t length) { - check(length); - memcpy(ptr, data, length); - ptr += length; - } - -- int length() { return ptr - start; } -+ size_t length() { return ptr - start; } - void clear() { ptr = start; }; - void clearAndZero() { memset(start, 0, ptr-start); clear(); } -- void reposition(int pos) { ptr = start + pos; } -+ void reposition(size_t pos) { ptr = start + pos; } - - // data() returns a pointer to the buffer. - -@@ -60,9 +60,9 @@ namespace rdr { - // overrun() either doubles the buffer or adds enough space for nItems of - // size itemSize bytes. - -- int overrun(int itemSize, int nItems) { -- int len = ptr - start + itemSize * nItems; -- if (len < (end - start) * 2) -+ size_t overrun(size_t itemSize, size_t nItems) { -+ size_t len = ptr - start + itemSize * nItems; -+ if (len < (size_t)(end - start) * 2) - len = (end - start) * 2; - - U8* newStart = new U8[len]; -diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h -index a749a20..11aafd2 100644 ---- a/common/rdr/OutStream.h -+++ b/common/rdr/OutStream.h -@@ -44,7 +44,7 @@ namespace rdr { - // itemSize bytes. Returns the number of items which fit (up to a maximum - // of nItems). - -- inline int check(int itemSize, int nItems=1) -+ inline size_t check(size_t itemSize, size_t nItems=1) - { - if (ptr + itemSize * nItems > end) { - if (ptr + itemSize > end) -@@ -76,13 +76,13 @@ namespace rdr { - writeBytes(str, len); - } - -- inline void pad(int bytes) { -+ inline void pad(size_t bytes) { - while (bytes-- > 0) writeU8(0); - } - -- inline void skip(int bytes) { -+ inline void skip(size_t bytes) { - while (bytes > 0) { -- int n = check(1, bytes); -+ size_t n = check(1, bytes); - ptr += n; - bytes -= n; - } -@@ -90,11 +90,11 @@ namespace rdr { - - // writeBytes() writes an exact number of bytes. - -- void writeBytes(const void* data, int length) { -+ void writeBytes(const void* data, size_t length) { - const U8* dataPtr = (const U8*)data; - const U8* dataEnd = dataPtr + length; - while (dataPtr < dataEnd) { -- int n = check(1, dataEnd - dataPtr); -+ size_t n = check(1, dataEnd - dataPtr); - memcpy(ptr, dataPtr, n); - ptr += n; - dataPtr += n; -@@ -103,9 +103,9 @@ namespace rdr { - - // copyBytes() efficiently transfers data between streams - -- void copyBytes(InStream* is, int length) { -+ void copyBytes(InStream* is, size_t length) { - while (length > 0) { -- int n = check(1, length); -+ size_t n = check(1, length); - is->readBytes(ptr, n); - ptr += n; - length -= n; -@@ -124,7 +124,7 @@ namespace rdr { - - // length() returns the length of the stream. - -- virtual int length() = 0; -+ virtual size_t length() = 0; - - // flush() requests that the stream be flushed. - -@@ -145,7 +145,7 @@ namespace rdr { - // the number of items which fit (up to a maximum of nItems). itemSize is - // supposed to be "small" (a few bytes). - -- virtual int overrun(int itemSize, int nItems) = 0; -+ virtual size_t overrun(size_t itemSize, size_t nItems) = 0; - - protected: - -diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx -index 3fde18d..7681095 100644 ---- a/common/rdr/RandomStream.cxx -+++ b/common/rdr/RandomStream.cxx -@@ -32,7 +32,7 @@ - - using namespace rdr; - --const int DEFAULT_BUF_LEN = 256; -+const size_t DEFAULT_BUF_LEN = 256; - - unsigned int RandomStream::seed; - -@@ -83,11 +83,11 @@ RandomStream::~RandomStream() { - #endif - } - --int RandomStream::pos() { -+size_t RandomStream::pos() { - return offset + ptr - start; - } - --int RandomStream::overrun(int itemSize, int nItems, bool wait) { -+size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) { - if (itemSize > DEFAULT_BUF_LEN) - throw Exception("RandomStream overrun: max itemSize exceeded"); - -@@ -98,7 +98,7 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) { - offset += ptr - start; - ptr = start; - -- int length = start + DEFAULT_BUF_LEN - end; -+ size_t length = start + DEFAULT_BUF_LEN - end; - - #ifdef RFB_HAVE_WINCRYPT - if (provider) { -@@ -109,7 +109,7 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) { - #else - #ifndef WIN32 - if (fp) { -- int n = fread((U8*)end, length, 1, fp); -+ size_t n = fread((U8*)end, length, 1, fp); - if (n != 1) - throw rdr::SystemException("reading /dev/urandom or /dev/random failed", - errno); -@@ -119,11 +119,11 @@ int RandomStream::overrun(int itemSize, int nItems, bool wait) { - { - #endif - #endif -- for (int i=0; i end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -diff --git a/common/rdr/RandomStream.h b/common/rdr/RandomStream.h -index c33360d..80b389b 100644 ---- a/common/rdr/RandomStream.h -+++ b/common/rdr/RandomStream.h -@@ -39,14 +39,14 @@ namespace rdr { - RandomStream(); - virtual ~RandomStream(); - -- int pos(); -+ size_t pos(); - - protected: -- int overrun(int itemSize, int nItems, bool wait); -+ size_t overrun(size_t itemSize, size_t nItems, bool wait); - - private: - U8* start; -- int offset; -+ size_t offset; - - static unsigned int seed; - #ifdef RFB_HAVE_WINCRYPT -diff --git a/common/rdr/SubstitutingInStream.h b/common/rdr/SubstitutingInStream.h -index 325b01c..1466fef 100644 ---- a/common/rdr/SubstitutingInStream.h -+++ b/common/rdr/SubstitutingInStream.h -@@ -45,9 +45,9 @@ namespace rdr { - delete [] subst; - } - -- int pos() { return underlying->pos(); } -+ size_t pos() { return underlying->pos(); } - -- virtual int overrun(int itemSize, int nItems, bool wait=true) { -+ virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) { - if (itemSize != 1) - throw new rdr::Exception("SubstitutingInStream: itemSize must be 1"); - -diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx -index 77b1672..d0f9426 100644 ---- a/common/rdr/TLSInStream.cxx -+++ b/common/rdr/TLSInStream.cxx -@@ -75,12 +75,12 @@ TLSInStream::~TLSInStream() - delete[] start; - } - --int TLSInStream::pos() -+size_t TLSInStream::pos() - { - return offset + ptr - start; - } - --int TLSInStream::overrun(int itemSize, int nItems, bool wait) -+size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait) - { - if (itemSize > bufSize) - throw Exception("TLSInStream overrun: max itemSize exceeded"); -@@ -93,19 +93,19 @@ int TLSInStream::overrun(int itemSize, int nItems, bool wait) - ptr = start; - - while (end < start + itemSize) { -- int n = readTLS((U8*) end, start + bufSize - end, wait); -+ size_t n = readTLS((U8*) end, start + bufSize - end, wait); - if (!wait && n == 0) - return 0; - end += n; - } - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; - } - --int TLSInStream::readTLS(U8* buf, int len, bool wait) -+size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait) - { - int n; - -diff --git a/common/rdr/TLSInStream.h b/common/rdr/TLSInStream.h -index b16d9f5..5f9dee7 100644 ---- a/common/rdr/TLSInStream.h -+++ b/common/rdr/TLSInStream.h -@@ -36,17 +36,17 @@ namespace rdr { - TLSInStream(InStream* in, gnutls_session_t session); - virtual ~TLSInStream(); - -- int pos(); -+ size_t pos(); - - private: -- int overrun(int itemSize, int nItems, bool wait); -- int readTLS(U8* buf, int len, bool wait); -+ size_t overrun(size_t itemSize, size_t nItems, bool wait); -+ size_t readTLS(U8* buf, size_t len, bool wait); - static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size); - - gnutls_session_t session; - InStream* in; -- int bufSize; -- int offset; -+ size_t bufSize; -+ size_t offset; - U8* start; - }; - }; -diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx -index 44d2d9f..30c456f 100644 ---- a/common/rdr/TLSOutStream.cxx -+++ b/common/rdr/TLSOutStream.cxx -@@ -75,7 +75,7 @@ TLSOutStream::~TLSOutStream() - delete [] start; - } - --int TLSOutStream::length() -+size_t TLSOutStream::length() - { - return offset + ptr - start; - } -@@ -84,7 +84,7 @@ void TLSOutStream::flush() - { - U8* sentUpTo = start; - while (sentUpTo < ptr) { -- int n = writeTLS(sentUpTo, ptr - sentUpTo); -+ size_t n = writeTLS(sentUpTo, ptr - sentUpTo); - sentUpTo += n; - offset += n; - } -@@ -93,20 +93,20 @@ void TLSOutStream::flush() - out->flush(); - } - --int TLSOutStream::overrun(int itemSize, int nItems) -+size_t TLSOutStream::overrun(size_t itemSize, size_t nItems) - { - if (itemSize > bufSize) - throw Exception("TLSOutStream overrun: max itemSize exceeded"); - - flush(); - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; - } - --int TLSOutStream::writeTLS(const U8* data, int length) -+size_t TLSOutStream::writeTLS(const U8* data, size_t length) - { - int n; - -diff --git a/common/rdr/TLSOutStream.h b/common/rdr/TLSOutStream.h -index 81dd237..71a7f3b 100644 ---- a/common/rdr/TLSOutStream.h -+++ b/common/rdr/TLSOutStream.h -@@ -36,20 +36,20 @@ namespace rdr { - virtual ~TLSOutStream(); - - void flush(); -- int length(); -+ size_t length(); - - protected: -- int overrun(int itemSize, int nItems); -+ size_t overrun(size_t itemSize, size_t nItems); - - private: -- int writeTLS(const U8* data, int length); -+ size_t writeTLS(const U8* data, size_t length); - static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size); - - gnutls_session_t session; - OutStream* out; -- int bufSize; -+ size_t bufSize; - U8* start; -- int offset; -+ size_t offset; - }; - }; - -diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx -index a361010..e2f971c 100644 ---- a/common/rdr/ZlibInStream.cxx -+++ b/common/rdr/ZlibInStream.cxx -@@ -26,7 +26,7 @@ using namespace rdr; - - enum { DEFAULT_BUF_SIZE = 16384 }; - --ZlibInStream::ZlibInStream(int bufSize_) -+ZlibInStream::ZlibInStream(size_t bufSize_) - : underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0), - zs(NULL), bytesIn(0) - { -@@ -40,14 +40,14 @@ ZlibInStream::~ZlibInStream() - delete [] start; - } - --void ZlibInStream::setUnderlying(InStream* is, int bytesIn_) -+void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_) - { - underlying = is; - bytesIn = bytesIn_; - ptr = end = start; - } - --int ZlibInStream::pos() -+size_t ZlibInStream::pos() - { - return offset + ptr - start; - } -@@ -96,7 +96,7 @@ void ZlibInStream::deinit() - zs = NULL; - } - --int ZlibInStream::overrun(int itemSize, int nItems, bool wait) -+size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait) - { - if (itemSize > bufSize) - throw Exception("ZlibInStream overrun: max itemSize exceeded"); -@@ -108,12 +108,12 @@ int ZlibInStream::overrun(int itemSize, int nItems, bool wait) - end -= ptr - start; - ptr = start; - -- while (end - ptr < itemSize) { -+ while ((size_t)(end - ptr) < itemSize) { - if (!decompress(wait)) - return 0; - } - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -@@ -131,11 +131,11 @@ bool ZlibInStream::decompress(bool wait) - zs->next_out = (U8*)end; - zs->avail_out = start + bufSize - end; - -- int n = underlying->check(1, 1, wait); -+ size_t n = underlying->check(1, 1, wait); - if (n == 0) return false; - zs->next_in = (U8*)underlying->getptr(); - zs->avail_in = underlying->getend() - underlying->getptr(); -- if ((int)zs->avail_in > bytesIn) -+ if (zs->avail_in > bytesIn) - zs->avail_in = bytesIn; - - int rc = inflate(zs, Z_SYNC_FLUSH); -diff --git a/common/rdr/ZlibInStream.h b/common/rdr/ZlibInStream.h -index 86ba1ff..08784b0 100644 ---- a/common/rdr/ZlibInStream.h -+++ b/common/rdr/ZlibInStream.h -@@ -34,12 +34,12 @@ namespace rdr { - - public: - -- ZlibInStream(int bufSize=0); -+ ZlibInStream(size_t bufSize=0); - virtual ~ZlibInStream(); - -- void setUnderlying(InStream* is, int bytesIn); -+ void setUnderlying(InStream* is, size_t bytesIn); - void flushUnderlying(); -- int pos(); -+ size_t pos(); - void reset(); - - private: -@@ -47,14 +47,14 @@ namespace rdr { - void init(); - void deinit(); - -- int overrun(int itemSize, int nItems, bool wait); -+ size_t overrun(size_t itemSize, size_t nItems, bool wait); - bool decompress(bool wait); - - InStream* underlying; -- int bufSize; -- int offset; -+ size_t bufSize; -+ size_t offset; - z_stream_s* zs; -- int bytesIn; -+ size_t bytesIn; - U8* start; - }; - -diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx -index 9d9f8ba..4e7ffd6 100644 ---- a/common/rdr/ZlibOutStream.cxx -+++ b/common/rdr/ZlibOutStream.cxx -@@ -30,7 +30,7 @@ using namespace rdr; - - enum { DEFAULT_BUF_SIZE = 16384 }; - --ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel) -+ZlibOutStream::ZlibOutStream(OutStream* os, size_t bufSize_, int compressLevel) - : underlying(os), compressionLevel(compressLevel), newLevel(compressLevel), - bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) - { -@@ -72,7 +72,7 @@ void ZlibOutStream::setCompressionLevel(int level) - newLevel = level; - } - --int ZlibOutStream::length() -+size_t ZlibOutStream::length() - { - return offset + ptr - start; - } -@@ -95,7 +95,7 @@ void ZlibOutStream::flush() - ptr = start; - } - --int ZlibOutStream::overrun(int itemSize, int nItems) -+size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems) - { - #ifdef ZLIBOUT_DEBUG - fprintf(stderr,"zos overrun\n"); -@@ -106,7 +106,7 @@ int ZlibOutStream::overrun(int itemSize, int nItems) - - checkCompressionLevel(); - -- while (end - ptr < itemSize) { -+ while ((size_t)(end - ptr) < itemSize) { - zs->next_in = start; - zs->avail_in = ptr - start; - -@@ -127,7 +127,7 @@ int ZlibOutStream::overrun(int itemSize, int nItems) - } - } - -- if (itemSize * nItems > end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - - return nItems; -diff --git a/common/rdr/ZlibOutStream.h b/common/rdr/ZlibOutStream.h -index 2d82a13..11bb046 100644 ---- a/common/rdr/ZlibOutStream.h -+++ b/common/rdr/ZlibOutStream.h -@@ -35,25 +35,25 @@ namespace rdr { - - public: - -- ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1); -+ ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1); - virtual ~ZlibOutStream(); - - void setUnderlying(OutStream* os); - void setCompressionLevel(int level=-1); - void flush(); -- int length(); -+ size_t length(); - - private: - -- int overrun(int itemSize, int nItems); -+ size_t overrun(size_t itemSize, size_t nItems); - void deflate(int flush); - void checkCompressionLevel(); - - OutStream* underlying; - int compressionLevel; - int newLevel; -- int bufSize; -- int offset; -+ size_t bufSize; -+ size_t offset; - z_stream_s* zs; - U8* start; - }; -diff --git a/common/rfb/Configuration.cxx b/common/rfb/Configuration.cxx -index 619c4d5..f35b0bc 100644 ---- a/common/rfb/Configuration.cxx -+++ b/common/rfb/Configuration.cxx -@@ -421,7 +421,7 @@ StringParameter::operator const char *() const { - // -=- BinaryParameter - - BinaryParameter::BinaryParameter(const char* name_, const char* desc_, -- const void* v, int l, ConfigurationObject co) -+ const void* v, size_t l, ConfigurationObject co) - : VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) { - if (l) { - value = new char[l]; -@@ -441,7 +441,7 @@ bool BinaryParameter::setParam(const char* v) { - return rdr::HexInStream::hexStrToBin(v, &value, &length); - } - --void BinaryParameter::setParam(const void* v, int len) { -+void BinaryParameter::setParam(const void* v, size_t len) { - LOCK_CONFIG; - if (immutable) return; - vlog.debug("set %s(Binary)", getName()); -@@ -462,7 +462,7 @@ char* BinaryParameter::getValueStr() const { - return rdr::HexOutStream::binToHexStr(value, length); - } - --void BinaryParameter::getData(void** data_, int* length_) const { -+void BinaryParameter::getData(void** data_, size_t* length_) const { - LOCK_CONFIG; - if (length_) *length_ = length; - if (data_) { -diff --git a/common/rfb/Configuration.h b/common/rfb/Configuration.h -index 6197317..e23e8a5 100644 ---- a/common/rfb/Configuration.h -+++ b/common/rfb/Configuration.h -@@ -256,24 +256,25 @@ namespace rfb { - - class BinaryParameter : public VoidParameter { - public: -- BinaryParameter(const char* name_, const char* desc_, const void* v, int l, -- ConfigurationObject co=ConfGlobal); -+ BinaryParameter(const char* name_, const char* desc_, -+ const void* v, size_t l, -+ ConfigurationObject co=ConfGlobal); - using VoidParameter::setParam; - virtual ~BinaryParameter(); - virtual bool setParam(const char* value); -- virtual void setParam(const void* v, int l); -+ virtual void setParam(const void* v, size_t l); - virtual char* getDefaultStr() const; - virtual char* getValueStr() const; - - // getData() will return length zero if there is no data - // NB: data may be set to zero, OR set to a zero-length buffer -- void getData(void** data, int* length) const; -+ void getData(void** data, size_t* length) const; - - protected: - char* value; -- int length; -+ size_t length; - char* def_value; -- int def_length; -+ size_t def_length; - }; - - // -=- ParameterIterator -diff --git a/common/rfb/Password.cxx b/common/rfb/Password.cxx -index 240c9d4..e4a508c 100644 ---- a/common/rfb/Password.cxx -+++ b/common/rfb/Password.cxx -@@ -38,7 +38,7 @@ PlainPasswd::PlainPasswd() {} - PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) { - } - --PlainPasswd::PlainPasswd(int len) : CharArray(len) { -+PlainPasswd::PlainPasswd(size_t len) : CharArray(len) { - } - - PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) { -@@ -63,11 +63,11 @@ void PlainPasswd::replaceBuf(char* b) { - ObfuscatedPasswd::ObfuscatedPasswd() : length(0) { - } - --ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) { -+ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) { - } - - ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) { -- int l = strlen(plainPwd.buf), i; -+ size_t l = strlen(plainPwd.buf), i; - for (i=0; i<8; i++) - buf[i] = i end - ptr) -+ if (itemSize * nItems > (size_t)(end - ptr)) - nItems = (end - ptr) / itemSize; - return nItems; - } -diff --git a/win/rfb_win32/Registry.cxx b/win/rfb_win32/Registry.cxx -index 963a36a..87086ad 100644 ---- a/win/rfb_win32/Registry.cxx -+++ b/win/rfb_win32/Registry.cxx -@@ -146,7 +146,7 @@ void RegKey::setString(const TCHAR* valname, const TCHAR* value) const { - if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result); - } - --void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const { -+void RegKey::setBinary(const TCHAR* valname, const void* value, size_t length) const { - LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length); - if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result); - } -@@ -169,12 +169,12 @@ TCHAR* RegKey::getString(const TCHAR* valname, const TCHAR* def) const { - } - } - --void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const { -+void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length) const { - TCharArray hex(getRepresentation(valname)); - if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length)) - throw rdr::Exception("getBinary failed"); - } --void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const { -+void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflen) const { - try { - getBinary(valname, data, length); - } catch(rdr::Exception&) { -diff --git a/win/rfb_win32/Registry.h b/win/rfb_win32/Registry.h -index 68d535c..2bb1691 100644 ---- a/win/rfb_win32/Registry.h -+++ b/win/rfb_win32/Registry.h -@@ -71,15 +71,15 @@ namespace rfb { - - void setExpandString(const TCHAR* valname, const TCHAR* s) const; - void setString(const TCHAR* valname, const TCHAR* s) const; -- void setBinary(const TCHAR* valname, const void* data, int length) const; -+ void setBinary(const TCHAR* valname, const void* data, size_t length) const; - void setInt(const TCHAR* valname, int i) const; - void setBool(const TCHAR* valname, bool b) const; - - TCHAR* getString(const TCHAR* valname) const; - TCHAR* getString(const TCHAR* valname, const TCHAR* def) const; - -- void getBinary(const TCHAR* valname, void** data, int* length) const; -- void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const; -+ void getBinary(const TCHAR* valname, void** data, size_t* length) const; -+ void getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflength) const; - - int getInt(const TCHAR* valname) const; - int getInt(const TCHAR* valname, int def) const; diff --git a/SOURCES/tigervnc-CVE-2019-15695.patch b/SOURCES/tigervnc-CVE-2019-15695.patch deleted file mode 100644 index 44c380c..0000000 --- a/SOURCES/tigervnc-CVE-2019-15695.patch +++ /dev/null @@ -1,17 +0,0 @@ -diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx -index a9d015d..896f4e5 100644 ---- a/common/rfb/PixelFormat.cxx -+++ b/common/rfb/PixelFormat.cxx -@@ -200,6 +200,12 @@ bool PixelFormat::is888(void) const - return false; - if (blueMax != 255) - return false; -+ if ((redShift & 0x7) != 0) -+ return false; -+ if ((greenShift & 0x7) != 0) -+ return false; -+ if ((blueShift & 0x7) != 0) -+ return false; - - return true; - } diff --git a/SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch b/SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch deleted file mode 100644 index 39216f2..0000000 --- a/SOURCES/tigervnc-add-write-protection-to-offsetpixelbuffer.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 9f615301aba1cc54a749950bf9462c5a85217bc4 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Tue, 10 Sep 2019 15:25:30 +0200 -Subject: [PATCH] Add write protection to OffsetPixelBuffer - -No one should every try to write to this buffer. Enforce that by -throwing an exception if any one tries to get a writeable pointer -to the data. ---- - common/rfb/EncodeManager.cxx | 6 ++++++ - common/rfb/EncodeManager.h | 3 +++ - 2 files changed, 9 insertions(+) - -diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx -index 1653cea..66ba432 100644 ---- a/common/rfb/EncodeManager.cxx -+++ b/common/rfb/EncodeManager.cxx -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -895,6 +896,11 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf, - setBuffer(width, height, (rdr::U8*)data_, stride_); - } - -+rdr::U8* EncodeManager::OffsetPixelBuffer::getBufferRW(const Rect& r, int* stride) -+{ -+ throw rfb::Exception("Invalid write attempt to OffsetPixelBuffer"); -+} -+ - // Preprocessor generated, optimised methods - - #define BPP 8 -diff --git a/common/rfb/EncodeManager.h b/common/rfb/EncodeManager.h -index 79db950..7d47420 100644 ---- a/common/rfb/EncodeManager.h -+++ b/common/rfb/EncodeManager.h -@@ -124,6 +124,9 @@ namespace rfb { - - void update(const PixelFormat& pf, int width, int height, - const rdr::U8* data_, int stride); -+ -+ private: -+ virtual rdr::U8* getBufferRW(const Rect& r, int* stride); - }; - - OffsetPixelBuffer offsetPixelBuffer; diff --git a/SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch b/SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch deleted file mode 100644 index 032d4c7..0000000 --- a/SOURCES/tigervnc-be-defensive-about-overflows-in-stream-objects.patch +++ /dev/null @@ -1,355 +0,0 @@ -From 75e6e0653a48baf474fd45d78b1da53e2f324642 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Tue, 24 Sep 2019 09:41:07 +0200 -Subject: [PATCH] Be defensive about overflows in stream objects - -We use a lot of lengths given to us over the network, so be more -paranoid about them causing an overflow as otherwise an attacker -might trick us in to overwriting other memory. - -This primarily affects the client which often gets lengths from the -server, but there are also some scenarios where the server might -theoretically be vulnerable. - -Issue found by Pavel Cheremushkin from Kaspersky Lab. ---- - common/rdr/FdInStream.cxx | 8 +++++--- - common/rdr/FdOutStream.cxx | 7 ++++--- - common/rdr/FileInStream.cxx | 8 +++++--- - common/rdr/HexInStream.cxx | 8 +++++--- - common/rdr/HexOutStream.cxx | 6 ++++-- - common/rdr/InStream.h | 24 +++++++++++++----------- - common/rdr/MemOutStream.h | 4 ++++ - common/rdr/OutStream.h | 24 +++++++++++++----------- - common/rdr/RandomStream.cxx | 6 ++++-- - common/rdr/TLSInStream.cxx | 10 ++++++---- - common/rdr/TLSOutStream.cxx | 6 ++++-- - common/rdr/ZlibInStream.cxx | 6 ++++-- - common/rdr/ZlibOutStream.cxx | 6 ++++-- - 13 files changed, 75 insertions(+), 48 deletions(-) - -diff --git a/common/rdr/FdInStream.cxx b/common/rdr/FdInStream.cxx -index 789cbec..406ece5 100644 ---- a/common/rdr/FdInStream.cxx -+++ b/common/rdr/FdInStream.cxx -@@ -136,7 +136,7 @@ size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait) - ptr = start; - - size_t bytes_to_read; -- while (end < start + itemSize) { -+ while ((size_t)(end - start) < itemSize) { - bytes_to_read = start + bufSize - end; - if (!timing) { - // When not timing, we must be careful not to read too much -@@ -152,8 +152,10 @@ size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait) - end += n; - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/FdOutStream.cxx b/common/rdr/FdOutStream.cxx -index 1757dc3..f5d07e4 100644 ---- a/common/rdr/FdOutStream.cxx -+++ b/common/rdr/FdOutStream.cxx -@@ -149,9 +149,10 @@ size_t FdOutStream::overrun(size_t itemSize, size_t nItems) - } - } - -- // Can we fit all the items asked for? -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/FileInStream.cxx b/common/rdr/FileInStream.cxx -index 94f5db8..bdb05a3 100644 ---- a/common/rdr/FileInStream.cxx -+++ b/common/rdr/FileInStream.cxx -@@ -68,7 +68,7 @@ size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait) - ptr = b; - - -- while (end < b + itemSize) { -+ while ((size_t)(end - b) < itemSize) { - size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file); - if (n == 0) { - if (ferror(file)) -@@ -80,8 +80,10 @@ size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait) - end += b + sizeof(b) - end; - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/HexInStream.cxx b/common/rdr/HexInStream.cxx -index 8f93988..a6bc92c 100644 ---- a/common/rdr/HexInStream.cxx -+++ b/common/rdr/HexInStream.cxx -@@ -91,7 +91,7 @@ size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) { - offset += ptr - start; - ptr = start; - -- while (end < ptr + itemSize) { -+ while ((size_t)(end - ptr) < itemSize) { - size_t n = in_stream.check(2, 1, wait); - if (n == 0) return 0; - const U8* iptr = in_stream.getptr(); -@@ -110,8 +110,10 @@ size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) { - end += length; - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/HexOutStream.cxx b/common/rdr/HexOutStream.cxx -index 7232514..eac2eff 100644 ---- a/common/rdr/HexOutStream.cxx -+++ b/common/rdr/HexOutStream.cxx -@@ -102,8 +102,10 @@ HexOutStream::overrun(size_t itemSize, size_t nItems) { - - writeBuffer(); - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/InStream.h b/common/rdr/InStream.h -index 14ecf09..f71a4d9 100644 ---- a/common/rdr/InStream.h -+++ b/common/rdr/InStream.h -@@ -43,12 +43,15 @@ namespace rdr { - - inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true) - { -- if (ptr + itemSize * nItems > end) { -- if (ptr + itemSize > end) -- return overrun(itemSize, nItems, wait); -+ size_t nAvail; -+ -+ if (itemSize > (size_t)(end - ptr)) -+ return overrun(itemSize, nItems, wait); -+ -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - -- nItems = (end - ptr) / itemSize; -- } - return nItems; - } - -@@ -93,13 +96,12 @@ namespace rdr { - // readBytes() reads an exact number of bytes. - - void readBytes(void* data, size_t length) { -- U8* dataPtr = (U8*)data; -- U8* dataEnd = dataPtr + length; -- while (dataPtr < dataEnd) { -- size_t n = check(1, dataEnd - dataPtr); -- memcpy(dataPtr, ptr, n); -+ while (length > 0) { -+ size_t n = check(1, length); -+ memcpy(data, ptr, n); - ptr += n; -- dataPtr += n; -+ data = (U8*)data + n; -+ length -= n; - } - } - -diff --git a/common/rdr/MemOutStream.h b/common/rdr/MemOutStream.h -index 4a815b3..b56bac3 100644 ---- a/common/rdr/MemOutStream.h -+++ b/common/rdr/MemOutStream.h -@@ -23,6 +23,7 @@ - #ifndef __RDR_MEMOUTSTREAM_H__ - #define __RDR_MEMOUTSTREAM_H__ - -+#include - #include - - namespace rdr { -@@ -65,6 +66,9 @@ namespace rdr { - if (len < (size_t)(end - start) * 2) - len = (end - start) * 2; - -+ if (len < (size_t)(end - start)) -+ throw Exception("Overflow in MemOutStream::overrun()"); -+ - U8* newStart = new U8[len]; - memcpy(newStart, start, ptr - start); - ptr = newStart + (ptr - start); -diff --git a/common/rdr/OutStream.h b/common/rdr/OutStream.h -index 11aafd2..0f60ccc 100644 ---- a/common/rdr/OutStream.h -+++ b/common/rdr/OutStream.h -@@ -46,12 +46,15 @@ namespace rdr { - - inline size_t check(size_t itemSize, size_t nItems=1) - { -- if (ptr + itemSize * nItems > end) { -- if (ptr + itemSize > end) -- return overrun(itemSize, nItems); -+ size_t nAvail; -+ -+ if (itemSize > (size_t)(end - ptr)) -+ return overrun(itemSize, nItems); -+ -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - -- nItems = (end - ptr) / itemSize; -- } - return nItems; - } - -@@ -91,13 +94,12 @@ namespace rdr { - // writeBytes() writes an exact number of bytes. - - void writeBytes(const void* data, size_t length) { -- const U8* dataPtr = (const U8*)data; -- const U8* dataEnd = dataPtr + length; -- while (dataPtr < dataEnd) { -- size_t n = check(1, dataEnd - dataPtr); -- memcpy(ptr, dataPtr, n); -+ while (length > 0) { -+ size_t n = check(1, length); -+ memcpy(ptr, data, n); - ptr += n; -- dataPtr += n; -+ data = (U8*)data + n; -+ length -= n; - } - } - -diff --git a/common/rdr/RandomStream.cxx b/common/rdr/RandomStream.cxx -index 7681095..6c64ac5 100644 ---- a/common/rdr/RandomStream.cxx -+++ b/common/rdr/RandomStream.cxx -@@ -123,8 +123,10 @@ size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) { - *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0)); - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/TLSInStream.cxx b/common/rdr/TLSInStream.cxx -index d0f9426..3e1172f 100644 ---- a/common/rdr/TLSInStream.cxx -+++ b/common/rdr/TLSInStream.cxx -@@ -43,7 +43,7 @@ ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size) - return -1; - } - -- if (in->getend() - in->getptr() < (ptrdiff_t)size) -+ if ((size_t)(in->getend() - in->getptr()) < size) - size = in->getend() - in->getptr(); - - in->readBytes(data, size); -@@ -92,15 +92,17 @@ size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait) - end -= ptr - start; - ptr = start; - -- while (end < start + itemSize) { -+ while ((size_t)(end - start) < itemSize) { - size_t n = readTLS((U8*) end, start + bufSize - end, wait); - if (!wait && n == 0) - return 0; - end += n; - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/TLSOutStream.cxx b/common/rdr/TLSOutStream.cxx -index 30c456f..7d7c3b5 100644 ---- a/common/rdr/TLSOutStream.cxx -+++ b/common/rdr/TLSOutStream.cxx -@@ -100,8 +100,10 @@ size_t TLSOutStream::overrun(size_t itemSize, size_t nItems) - - flush(); - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/ZlibInStream.cxx b/common/rdr/ZlibInStream.cxx -index e2f971c..9fcfaf6 100644 ---- a/common/rdr/ZlibInStream.cxx -+++ b/common/rdr/ZlibInStream.cxx -@@ -113,8 +113,10 @@ size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait) - return 0; - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } -diff --git a/common/rdr/ZlibOutStream.cxx b/common/rdr/ZlibOutStream.cxx -index 4e7ffd6..5e158bf 100644 ---- a/common/rdr/ZlibOutStream.cxx -+++ b/common/rdr/ZlibOutStream.cxx -@@ -127,8 +127,10 @@ size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems) - } - } - -- if (itemSize * nItems > (size_t)(end - ptr)) -- nItems = (end - ptr) / itemSize; -+ size_t nAvail; -+ nAvail = (end - ptr) / itemSize; -+ if (nAvail < nItems) -+ return nAvail; - - return nItems; - } diff --git a/SOURCES/tigervnc-covscan.patch b/SOURCES/tigervnc-covscan.patch deleted file mode 100644 index 803f71a..0000000 --- a/SOURCES/tigervnc-covscan.patch +++ /dev/null @@ -1,312 +0,0 @@ -diff --git a/common/network/TcpSocket.cxx b/common/network/TcpSocket.cxx -index 51d77c76..9e277cbb 100644 ---- a/common/network/TcpSocket.cxx -+++ b/common/network/TcpSocket.cxx -@@ -736,7 +736,7 @@ char* TcpFilter::patternToStr(const TcpFilter::Pattern& p) { - buffer + 1, sizeof (buffer) - 2, NULL, 0, NI_NUMERICHOST); - strcat(buffer, "]"); - addr.buf = rfb::strDup(buffer); -- } else if (p.address.u.sa.sa_family == AF_UNSPEC) -+ } else - addr.buf = rfb::strDup(""); - - char action; -diff --git a/common/rfb/CSecurityTLS.cxx b/common/rfb/CSecurityTLS.cxx -index e1a31f78..d268202b 100644 ---- a/common/rfb/CSecurityTLS.cxx -+++ b/common/rfb/CSecurityTLS.cxx -@@ -95,9 +95,9 @@ void CSecurityTLS::setDefaults() - delete [] homeDir; - - if (!fileexists(caDefault.buf)) -- X509CA.setDefaultStr(strdup(caDefault.buf)); -+ X509CA.setDefaultStr(caDefault.buf); - if (!fileexists(crlDefault.buf)) -- X509CRL.setDefaultStr(strdup(crlDefault.buf)); -+ X509CRL.setDefaultStr(crlDefault.buf); - } - - void CSecurityTLS::shutdown(bool needbye) -diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx -index 6d48b65c..6f72432a 100644 ---- a/common/rfb/SSecurityPlain.cxx -+++ b/common/rfb/SSecurityPlain.cxx -@@ -41,7 +41,7 @@ StringParameter PasswordValidator::plainUsers - - bool PasswordValidator::validUser(const char* username) - { -- CharArray users(strDup(plainUsers.getValueStr())), user; -+ CharArray users(plainUsers.getValueStr()), user; - - while (users.buf) { - strSplit(users.buf, ',', &user.buf, &users.buf); -diff --git a/unix/tx/TXWindow.cxx b/unix/tx/TXWindow.cxx -index a6819179..6129840e 100644 ---- a/unix/tx/TXWindow.cxx -+++ b/unix/tx/TXWindow.cxx -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - - std::list windows; -@@ -132,20 +133,20 @@ TXGlobalEventHandler* TXWindow::setGlobalEventHandler(TXGlobalEventHandler* h) - - void TXWindow::getColours(Display* dpy, XColor* cols, int nCols) - { -- bool* got = new bool[nCols]; -+ std::vector got; -+ - bool failed = false; - int i; - for (i = 0; i < nCols; i++) { - if (XAllocColor(dpy, cmap, &cols[i])) { -- got[i] = true; -+ got.push_back(true); - } else { -- got[i] = false; -+ got.push_back(false); - failed = true; - } - } - - if (!failed) { -- delete [] got; - return; - } - -@@ -168,12 +169,13 @@ void TXWindow::getColours(Display* dpy, XColor* cols, int nCols) - int cmapSize = DisplayCells(dpy,DefaultScreen(dpy)); - - XColor* cm = new XColor[cmapSize]; -- bool* shared = new bool[cmapSize]; -- bool* usedAsNearest = new bool[cmapSize]; -+ std::vector shared; -+ std::vector usedAsNearest; - - for (i = 0; i < cmapSize; i++) { - cm[i].pixel = i; -- shared[i] = usedAsNearest[i] = false; -+ shared.push_back(false); -+ usedAsNearest.push_back(false); - } - - XQueryColors(dpy, cmap, cm, cmapSize); -diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx -index 8bd4e48e..3055223e 100644 ---- a/unix/vncpasswd/vncpasswd.cxx -+++ b/unix/vncpasswd/vncpasswd.cxx -@@ -134,7 +134,7 @@ int main(int argc, char** argv) - } else if (argv[i][0] == '-') { - usage(); - } else if (!fname) { -- fname = argv[i]; -+ fname = strDup(argv[i]); - } else { - usage(); - } -@@ -165,24 +165,37 @@ int main(int argc, char** argv) - FILE* fp = fopen(fname,"w"); - if (!fp) { - fprintf(stderr,"Couldn't open %s for writing\n",fname); -+ delete [] fname; -+ delete obfuscated; -+ delete obfuscatedReadOnly; - exit(1); - } - chmod(fname, S_IRUSR|S_IWUSR); - - if (fwrite(obfuscated->buf, obfuscated->length, 1, fp) != 1) { - fprintf(stderr,"Writing to %s failed\n",fname); -+ delete [] fname; -+ delete obfuscated; -+ delete obfuscatedReadOnly; - exit(1); - } - -+ delete obfuscated; -+ - if (obfuscatedReadOnly) { - if (fwrite(obfuscatedReadOnly->buf, obfuscatedReadOnly->length, 1, fp) != 1) { - fprintf(stderr,"Writing to %s failed\n",fname); -+ delete [] fname; -+ delete obfuscatedReadOnly; - exit(1); - } - } - - fclose(fp); - -+ delete [] fname; -+ delete obfuscatedReadOnly; -+ - return 0; - } - } -diff --git a/unix/xserver/hw/vnc/vncExtInit.cc b/unix/xserver/hw/vnc/vncExtInit.cc -index d6f6b742..7ca71d94 100644 ---- a/unix/xserver/hw/vnc/vncExtInit.cc -+++ b/unix/xserver/hw/vnc/vncExtInit.cc -@@ -184,7 +184,7 @@ void vncExtensionInit(void) - listeners.push_back(new network::TcpListener(vncInetdSock)); - vlog.info("inetd wait"); - } -- } else if (rfbunixpath.getValueStr()[0] != '\0') { -+ } else if (((const char*)rfbunixpath)[0] != '\0') { - char path[PATH_MAX]; - int mode = (int)rfbunixmode; - -@@ -192,7 +192,7 @@ void vncExtensionInit(void) - strncpy(path, rfbunixpath, sizeof(path)); - else - snprintf(path, sizeof(path), "%s.%d", -- rfbunixpath.getValueStr(), scr); -+ (const char*)rfbunixpath, scr); - path[sizeof(path)-1] = '\0'; - - listeners.push_back(new network::UnixListener(path, mode)); -diff --git a/unix/xserver/hw/vnc/vncSelection.c b/unix/xserver/hw/vnc/vncSelection.c -index 51dfd9c6..4f3538d4 100644 ---- a/unix/xserver/hw/vnc/vncSelection.c -+++ b/unix/xserver/hw/vnc/vncSelection.c -@@ -105,7 +105,7 @@ void vncClientCutText(const char* str, int len) - LOG_ERROR("Could not set PRIMARY selection"); - } - -- vncOwnSelection(xaCLIPBOARD); -+ rc = vncOwnSelection(xaCLIPBOARD); - if (rc != Success) - LOG_ERROR("Could not set CLIPBOARD selection"); - } -diff --git a/unix/xserver/hw/vnc/xvnc.c b/unix/xserver/hw/vnc/xvnc.c -index 3b4d2f31..c845ebc4 100644 ---- a/unix/xserver/hw/vnc/xvnc.c -+++ b/unix/xserver/hw/vnc/xvnc.c -@@ -766,10 +766,13 @@ vfbUninstallColormap(ColormapPtr pmap) - curpmap = (ColormapPtr) LookupIDByType(pmap->pScreen->defColormap, - RT_COLORMAP); - #else -- dixLookupResourceByType((void * *) &curpmap, pmap->pScreen->defColormap, -- RT_COLORMAP, serverClient, DixUnknownAccess); -+ int rc = dixLookupResourceByType((void * *) &curpmap, pmap->pScreen->defColormap, -+ RT_COLORMAP, serverClient, DixUnknownAccess); -+ if (rc != Success) -+ ErrorF("Failed to uninstall color map\n"); -+ else - #endif -- (*pmap->pScreen->InstallColormap)(curpmap); -+ (*pmap->pScreen->InstallColormap)(curpmap); - } - } - } -diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx -index d070b648..1843485a 100644 ---- a/vncviewer/DesktopWindow.cxx -+++ b/vncviewer/DesktopWindow.cxx -@@ -103,12 +103,12 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name, - int geom_x = 0, geom_y = 0; - if (strcmp(geometry, "") != 0) { - int matched; -- matched = sscanf(geometry.getValueStr(), "+%d+%d", &geom_x, &geom_y); -+ matched = sscanf((const char*)geometry, "+%d+%d", &geom_x, &geom_y); - if (matched == 2) { - force_position(1); - } else { - int geom_w, geom_h; -- matched = sscanf(geometry.getValueStr(), "%dx%d+%d+%d", &geom_w, &geom_h, &geom_x, &geom_y); -+ matched = sscanf((const char*)geometry, "%dx%d+%d+%d", &geom_w, &geom_h, &geom_x, &geom_y); - switch (matched) { - case 4: - force_position(1); -diff --git a/vncviewer/OptionsDialog.cxx b/vncviewer/OptionsDialog.cxx -index b018c95b..62b5d9c5 100644 ---- a/vncviewer/OptionsDialog.cxx -+++ b/vncviewer/OptionsDialog.cxx -@@ -282,7 +282,7 @@ void OptionsDialog::loadOptions(void) - /* Screen */ - int width, height; - -- if (sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) != 2) { -+ if (sscanf((const char*)desktopSize, "%dx%d", &width, &height) != 2) { - desktopSizeCheckbox->value(false); - desktopWidthInput->value("1024"); - desktopHeightInput->value("768"); -diff --git a/vncviewer/ServerDialog.cxx b/vncviewer/ServerDialog.cxx -index de67f87b..fec17896 100644 ---- a/vncviewer/ServerDialog.cxx -+++ b/vncviewer/ServerDialog.cxx -@@ -150,7 +150,7 @@ void ServerDialog::handleLoad(Fl_Widget *widget, void *data) - return; - } - -- const char* filename = strdup(file_chooser->value()); -+ const char* filename = file_chooser->value(); - - try { - dialog->serverName->value(loadViewerParameters(filename)); -@@ -165,8 +165,8 @@ void ServerDialog::handleLoad(Fl_Widget *widget, void *data) - void ServerDialog::handleSaveAs(Fl_Widget *widget, void *data) - { - ServerDialog *dialog = (ServerDialog*)data; -- const char* servername = strdup(dialog->serverName->value()); -- char* filename; -+ const char* servername = dialog->serverName->value(); -+ const char* filename; - - Fl_File_Chooser* file_chooser = new Fl_File_Chooser("", _("TigerVNC configuration (*.tigervnc)"), - 2, _("Save the TigerVNC configuration to file")); -@@ -187,7 +187,7 @@ void ServerDialog::handleSaveAs(Fl_Widget *widget, void *data) - return; - } - -- filename = strdup(file_chooser->value()); -+ filename = file_chooser->value(); - - FILE* f = fopen(filename, "r"); - if (f) { -@@ -235,7 +235,7 @@ void ServerDialog::handleCancel(Fl_Widget *widget, void *data) - void ServerDialog::handleConnect(Fl_Widget *widget, void *data) - { - ServerDialog *dialog = (ServerDialog*)data; -- const char* servername = strdup(dialog->serverName->value()); -+ const char* servername = dialog->serverName->value(); - - dialog->hide(); - -diff --git a/vncviewer/parameters.cxx b/vncviewer/parameters.cxx -index 51cce3d7..94cc1b05 100644 ---- a/vncviewer/parameters.cxx -+++ b/vncviewer/parameters.cxx -@@ -499,6 +499,7 @@ void saveViewerParameters(const char *filename, const char *servername) { - } - - snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir); -+ free(homeDir); - } else { - snprintf(filepath, sizeof(filepath), "%s", filename); - } -@@ -555,6 +556,7 @@ char* loadViewerParameters(const char *filename) { - "can't obtain home directory path.")); - - snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir); -+ free(homeDir); - } else { - snprintf(filepath, sizeof(filepath), "%s", filename); - } -diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx -index f076565f..a9d4dfea 100644 ---- a/vncviewer/vncviewer.cxx -+++ b/vncviewer/vncviewer.cxx -@@ -470,9 +470,9 @@ static int mktunnel() - int localPort = findFreeTcpPort(); - int remotePort; - -- gatewayHost = strDup(via.getValueStr()); - if (interpretViaParam(remoteHost, &remotePort, localPort) != 0) - return 1; -+ gatewayHost = (const char*)via; - createTunnel(gatewayHost, remoteHost, remotePort, localPort); - - return 0; diff --git a/SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch b/SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch deleted file mode 100644 index 795a8f1..0000000 --- a/SOURCES/tigervnc-encapsulate-pixelbuffer-internal-details.patch +++ /dev/null @@ -1,526 +0,0 @@ -From 53f913a76196c7357d4858bfbf2c33caa9181bae Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Tue, 10 Sep 2019 15:18:30 +0200 -Subject: [PATCH] Encapsulate PixelBuffer internal details - -Don't allow subclasses to just override dimensions or buffer details -directly and instead force them to go via methods. This allows us -to do sanity checks on the new values and catch bugs and attacks. ---- - common/rfb/Cursor.cxx | 3 +- - common/rfb/EncodeManager.cxx | 5 +- - common/rfb/PixelBuffer.cxx | 103 ++++++++++++++++---------- - common/rfb/PixelBuffer.h | 17 +++-- - unix/x0vncserver/XPixelBuffer.cxx | 9 +-- - unix/xserver/hw/vnc/XserverDesktop.cc | 24 +++--- - unix/xserver/hw/vnc/XserverDesktop.h | 2 +- - vncviewer/PlatformPixelBuffer.cxx | 9 +-- - win/rfb_win32/DIBSectionBuffer.cxx | 41 ++++------ - 9 files changed, 111 insertions(+), 102 deletions(-) - -diff --git a/common/rfb/Cursor.cxx b/common/rfb/Cursor.cxx -index 99df82d..7f3fc9a 100644 ---- a/common/rfb/Cursor.cxx -+++ b/common/rfb/Cursor.cxx -@@ -271,8 +271,7 @@ void RenderedCursor::update(PixelBuffer* framebuffer, - assert(cursor); - - format = framebuffer->getPF(); -- width_ = framebuffer->width(); -- height_ = framebuffer->height(); -+ setSize(framebuffer->width(), framebuffer->height()); - - rawOffset = pos.subtract(cursor->hotspot()); - clippedRect = Rect(0, 0, cursor->width(), cursor->height()) -diff --git a/common/rfb/EncodeManager.cxx b/common/rfb/EncodeManager.cxx -index 0ce611e..11f31d3 100644 ---- a/common/rfb/EncodeManager.cxx -+++ b/common/rfb/EncodeManager.cxx -@@ -979,11 +979,8 @@ void EncodeManager::OffsetPixelBuffer::update(const PixelFormat& pf, - int stride_) - { - format = pf; -- width_ = width; -- height_ = height; - // Forced cast. We never write anything though, so it should be safe. -- data = (rdr::U8*)data_; -- stride = stride_; -+ setBuffer(width, height, (rdr::U8*)data_, stride_); - } - - // Preprocessor generated, optimised methods -diff --git a/common/rfb/PixelBuffer.cxx b/common/rfb/PixelBuffer.cxx -index 007b6c8..ad58324 100644 ---- a/common/rfb/PixelBuffer.cxx -+++ b/common/rfb/PixelBuffer.cxx -@@ -35,8 +35,14 @@ static LogWriter vlog("PixelBuffer"); - // -=- Generic pixel buffer class - - PixelBuffer::PixelBuffer(const PixelFormat& pf, int w, int h) -- : format(pf), width_(w), height_(h) {} --PixelBuffer::PixelBuffer() : width_(0), height_(0) {} -+ : format(pf), width_(0), height_(0) -+{ -+ setSize(w, h); -+} -+ -+PixelBuffer::PixelBuffer() : width_(0), height_(0) -+{ -+} - - PixelBuffer::~PixelBuffer() {} - -@@ -53,7 +59,7 @@ PixelBuffer::getImage(void* imageBuf, const Rect& r, int outStride) const - if (!r.enclosed_by(getRect())) - throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d", - r.width(), r.height(), -- r.tl.x, r.tl.y, width_, height_); -+ r.tl.x, r.tl.y, width(), height()); - - data = getBuffer(r, &inStride); - -@@ -89,7 +95,7 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf, - if (!r.enclosed_by(getRect())) - throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d", - r.width(), r.height(), -- r.tl.x, r.tl.y, width_, height_); -+ r.tl.x, r.tl.y, width(), height()); - - if (stride == 0) - stride = r.width(); -@@ -100,6 +106,12 @@ void PixelBuffer::getImage(const PixelFormat& pf, void* imageBuf, - stride, srcStride); - } - -+void PixelBuffer::setSize(int width, int height) -+{ -+ width_ = width; -+ height_ = height; -+} -+ - // -=- Modifiable generic pixel buffer class - - ModifiablePixelBuffer::ModifiablePixelBuffer(const PixelFormat& pf, -@@ -124,7 +136,7 @@ void ModifiablePixelBuffer::fillRect(const Rect& r, const void* pix) - - if (!r.enclosed_by(getRect())) - throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", -- r.width(), r.height(), r.tl.x, r.tl.y, width_, height_); -+ r.width(), r.height(), r.tl.x, r.tl.y, width(), height()); - - w = r.width(); - h = r.height(); -@@ -175,7 +187,7 @@ void ModifiablePixelBuffer::imageRect(const Rect& r, - if (!r.enclosed_by(getRect())) - throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", - r.width(), r.height(), -- r.tl.x, r.tl.y, width_, height_); -+ r.tl.x, r.tl.y, width(), height()); - - bytesPerPixel = getPF().bpp/8; - -@@ -213,13 +225,13 @@ void ModifiablePixelBuffer::copyRect(const Rect &rect, - if (!drect.enclosed_by(getRect())) - throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", - drect.width(), drect.height(), -- drect.tl.x, drect.tl.y, width_, height_); -+ drect.tl.x, drect.tl.y, width(), height()); - - srect = drect.translate(move_by_delta.negate()); - if (!srect.enclosed_by(getRect())) - throw rfb::Exception("Source rect %dx%d at %d,%d exceeds framebuffer %dx%d", - srect.width(), srect.height(), -- srect.tl.x, srect.tl.y, width_, height_); -+ srect.tl.x, srect.tl.y, width(), height()); - - srcData = getBuffer(srect, &srcStride); - dstData = getBufferRW(drect, &dstStride); -@@ -272,7 +284,7 @@ void ModifiablePixelBuffer::imageRect(const PixelFormat& pf, const Rect &dest, - if (!dest.enclosed_by(getRect())) - throw rfb::Exception("Destination rect %dx%d at %d,%d exceeds framebuffer %dx%d", - dest.width(), dest.height(), -- dest.tl.x, dest.tl.y, width_, height_); -+ dest.tl.x, dest.tl.y, width(), height()); - - if (stride == 0) - stride = dest.width(); -@@ -301,7 +313,7 @@ rdr::U8* FullFramePixelBuffer::getBufferRW(const Rect& r, int* stride_) - if (!r.enclosed_by(getRect())) - throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d", - r.width(), r.height(), -- r.tl.x, r.tl.y, width_, height_); -+ r.tl.x, r.tl.y, width(), height()); - - *stride_ = stride; - return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8]; -@@ -316,55 +328,69 @@ const rdr::U8* FullFramePixelBuffer::getBuffer(const Rect& r, int* stride_) cons - if (!r.enclosed_by(getRect())) - throw rfb::Exception("Pixel buffer request %dx%d at %d,%d exceeds framebuffer %dx%d", - r.width(), r.height(), -- r.tl.x, r.tl.y, width_, height_); -+ r.tl.x, r.tl.y, width(), height()); - - *stride_ = stride; - return &data[(r.tl.x + (r.tl.y * stride)) * format.bpp/8]; - } - -+void FullFramePixelBuffer::setBuffer(int width, int height, -+ rdr::U8* data_, int stride_) -+{ -+ ModifiablePixelBuffer::setSize(width, height); -+ stride = stride_; -+ data = data_; -+} -+ -+void FullFramePixelBuffer::setSize(int w, int h) -+{ -+ // setBuffer() should be used -+ throw rfb::Exception("Invalid call to FullFramePixelBuffer::setSize()"); -+} -+ - // -=- Managed pixel buffer class - // Automatically allocates enough space for the specified format & area - - ManagedPixelBuffer::ManagedPixelBuffer() -- : datasize(0) -+ : data_(NULL), datasize(0) - { -- checkDataSize(); - }; - - ManagedPixelBuffer::ManagedPixelBuffer(const PixelFormat& pf, int w, int h) -- : FullFramePixelBuffer(pf, w, h, NULL, w), datasize(0) -+ : FullFramePixelBuffer(pf, 0, 0, NULL, 0), data_(NULL), datasize(0) - { -- checkDataSize(); --}; -+ setSize(w, h); -+} - --ManagedPixelBuffer::~ManagedPixelBuffer() { -- if (data) delete [] data; --}; -+ManagedPixelBuffer::~ManagedPixelBuffer() -+{ -+ if (data_) -+ delete [] data_; -+} - -+void ManagedPixelBuffer::setPF(const PixelFormat &pf) -+{ -+ format = pf; -+ setSize(width(), height()); -+} - --void --ManagedPixelBuffer::setPF(const PixelFormat &pf) { -- format = pf; checkDataSize(); --}; --void --ManagedPixelBuffer::setSize(int w, int h) { -- width_ = w; height_ = h; stride = w; checkDataSize(); --}; -+void ManagedPixelBuffer::setSize(int w, int h) -+{ -+ unsigned long new_datasize = w * h * (format.bpp/8); - -+ new_datasize = w * h * (format.bpp/8); - --inline void --ManagedPixelBuffer::checkDataSize() { -- unsigned long new_datasize = width_ * height_ * (format.bpp/8); - if (datasize < new_datasize) { -- if (data) { -- delete [] data; -- datasize = 0; data = 0; -+ if (data_) { -+ delete [] data_; -+ data_ = NULL; -+ datasize = 0; - } - if (new_datasize) { -- data = new U8[new_datasize]; -- if (!data) -- throw Exception("rfb::ManagedPixelBuffer unable to allocate buffer"); -+ data_ = new U8[new_datasize]; - datasize = new_datasize; - } - } --}; -+ -+ setBuffer(w, h, data_, w); -+} -diff --git a/common/rfb/PixelBuffer.h b/common/rfb/PixelBuffer.h -index d89793f..3e4018f 100644 ---- a/common/rfb/PixelBuffer.h -+++ b/common/rfb/PixelBuffer.h -@@ -90,7 +90,12 @@ namespace rfb { - - protected: - PixelBuffer(); -+ virtual void setSize(int width, int height); -+ -+ protected: - PixelFormat format; -+ -+ private: - int width_, height_; - }; - -@@ -154,7 +159,12 @@ namespace rfb { - - protected: - FullFramePixelBuffer(); -+ virtual void setBuffer(int width, int height, rdr::U8* data, int stride); - -+ private: -+ virtual void setSize(int w, int h); -+ -+ private: - rdr::U8* data; - int stride; - }; -@@ -172,12 +182,9 @@ namespace rfb { - virtual void setPF(const PixelFormat &pf); - virtual void setSize(int w, int h); - -- // Return the total number of bytes of pixel data in the buffer -- int dataLen() const { return width_ * height_ * (format.bpp/8); } -- -- protected: -+ private: -+ rdr::U8* data_; // Mirrors FullFramePixelBuffer::data - unsigned long datasize; -- void checkDataSize(); - }; - - }; -diff --git a/unix/x0vncserver/XPixelBuffer.cxx b/unix/x0vncserver/XPixelBuffer.cxx -index 4769b65..f0b0696 100644 ---- a/unix/x0vncserver/XPixelBuffer.cxx -+++ b/unix/x0vncserver/XPixelBuffer.cxx -@@ -50,13 +50,8 @@ XPixelBuffer::XPixelBuffer(Display *dpy, ImageFactory &factory, - ffs(m_image->xim->blue_mask) - 1); - - // Set up the remaining data of the parent class. -- width_ = rect.width(); -- height_ = rect.height(); -- data = (rdr::U8 *)m_image->xim->data; -- -- // Calculate the distance in pixels between two subsequent scan -- // lines of the framebuffer. This may differ from image width. -- stride = m_image->xim->bytes_per_line * 8 / m_image->xim->bits_per_pixel; -+ setBuffer(rect.width(), rect.height(), (rdr::U8 *)m_image->xim->data, -+ m_image->xim->bytes_per_line * 8 / m_image->xim->bits_per_pixel); - - // Get initial screen image from the X display. - m_image->get(DefaultRootWindow(m_dpy), m_offsetLeft, m_offsetTop); -diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc -index 4aac765..78df899 100644 ---- a/unix/xserver/hw/vnc/XserverDesktop.cc -+++ b/unix/xserver/hw/vnc/XserverDesktop.cc -@@ -115,7 +115,7 @@ XserverDesktop::XserverDesktop(int screenIndex_, - : screenIndex(screenIndex_), - server(0), httpServer(0), - listeners(listeners_), httpListeners(httpListeners_), -- directFbptr(true), -+ shadowFramebuffer(NULL), - queryConnectId(0), queryConnectTimer(this) - { - format = pf; -@@ -152,8 +152,8 @@ XserverDesktop::~XserverDesktop() - delete httpListeners.back(); - httpListeners.pop_back(); - } -- if (!directFbptr) -- delete [] data; -+ if (shadowFramebuffer) -+ delete [] shadowFramebuffer; - delete httpServer; - delete server; - } -@@ -172,22 +172,18 @@ void XserverDesktop::setFramebuffer(int w, int h, void* fbptr, int stride_) - { - ScreenSet layout; - -- width_ = w; -- height_ = h; -- -- if (!directFbptr) { -- delete [] data; -- directFbptr = true; -+ if (shadowFramebuffer) { -+ delete [] shadowFramebuffer; -+ shadowFramebuffer = NULL; - } - - if (!fbptr) { -- fbptr = new rdr::U8[w * h * (format.bpp/8)]; -+ shadowFramebuffer = new rdr::U8[w * h * (format.bpp/8)]; -+ fbptr = shadowFramebuffer; - stride_ = w; -- directFbptr = false; - } - -- data = (rdr::U8*)fbptr; -- stride = stride_; -+ setBuffer(w, h, (rdr::U8*)fbptr, stride_); - - vncSetGlueContext(screenIndex); - layout = ::computeScreenLayout(&outputIdMap); -@@ -569,7 +565,7 @@ unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height, - - void XserverDesktop::grabRegion(const rfb::Region& region) - { -- if (directFbptr) -+ if (shadowFramebuffer == NULL) - return; - - std::vector rects; -diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h -index f866a4c..dc4fe60 100644 ---- a/unix/xserver/hw/vnc/XserverDesktop.h -+++ b/unix/xserver/hw/vnc/XserverDesktop.h -@@ -124,7 +124,7 @@ private: - rfb::HTTPServer* httpServer; - std::list listeners; - std::list httpListeners; -- bool directFbptr; -+ rdr::U8* shadowFramebuffer; - - uint32_t queryConnectId; - network::Socket* queryConnectSocket; -diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx -index a2b506d..a218901 100644 ---- a/vncviewer/PlatformPixelBuffer.cxx -+++ b/vncviewer/PlatformPixelBuffer.cxx -@@ -36,7 +36,7 @@ static rfb::LogWriter vlog("PlatformPixelBuffer"); - PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : - FullFramePixelBuffer(rfb::PixelFormat(32, 24, false, true, - 255, 255, 255, 16, 8, 0), -- width, height, 0, stride), -+ 0, 0, NULL, 0), - Surface(width, height) - #if !defined(WIN32) && !defined(__APPLE__) - , shminfo(NULL), xim(NULL) -@@ -56,11 +56,10 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : - vlog.debug("Using standard XImage"); - } - -- data = (rdr::U8*)xim->data; -- stride = xim->bytes_per_line / (getPF().bpp/8); -+ setBuffer(width, height, (rdr::U8*)xim->data, -+ xim->bytes_per_line / (getPF().bpp/8)); - #else -- FullFramePixelBuffer::data = (rdr::U8*)Surface::data; -- stride = width; -+ setBuffer(width, height, (rdr::U8*)Surface::data, width); - #endif - } - -diff --git a/win/rfb_win32/DIBSectionBuffer.cxx b/win/rfb_win32/DIBSectionBuffer.cxx -index e2b0d64..e00cf23 100644 ---- a/win/rfb_win32/DIBSectionBuffer.cxx -+++ b/win/rfb_win32/DIBSectionBuffer.cxx -@@ -52,39 +52,28 @@ void DIBSectionBuffer::setPF(const PixelFormat& pf) { - if (!pf.trueColour) - throw rfb::Exception("palette format not supported"); - format = pf; -- recreateBuffer(); -+ setSize(width(), height()); - } - --void DIBSectionBuffer::setSize(int w, int h) { -- if (width_ == w && height_ == h) { -- vlog.debug("size unchanged by setSize()"); -- return; -- } -- width_ = w; -- height_ = h; -- recreateBuffer(); --} -- -- - inline void initMaxAndShift(DWORD mask, int* max, int* shift) { - for ((*shift) = 0; (mask & 1) == 0; (*shift)++) mask >>= 1; - (*max) = (rdr::U16)mask; - } - --void DIBSectionBuffer::recreateBuffer() { -+void DIBSectionBuffer::setSize(int w, int h) { - HBITMAP new_bitmap = 0; - rdr::U8* new_data = 0; - -- if (width_ && height_ && (format.depth != 0)) { -+ if (w && h && (format.depth != 0)) { - BitmapInfo bi; - memset(&bi, 0, sizeof(bi)); - UINT iUsage = DIB_RGB_COLORS; - bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biBitCount = format.bpp; -- bi.bmiHeader.biSizeImage = (format.bpp / 8) * width_ * height_; -+ bi.bmiHeader.biSizeImage = (format.bpp / 8) * w * h; - bi.bmiHeader.biPlanes = 1; -- bi.bmiHeader.biWidth = width_; -- bi.bmiHeader.biHeight = -height_; -+ bi.bmiHeader.biWidth = w; -+ bi.bmiHeader.biHeight = -h; - bi.bmiHeader.biCompression = (format.bpp > 8) ? BI_BITFIELDS : BI_RGB; - bi.mask.red = format.pixelFromRGB((rdr::U16)~0, 0, 0); - bi.mask.green = format.pixelFromRGB(0, (rdr::U16)~0, 0); -@@ -115,12 +104,12 @@ void DIBSectionBuffer::recreateBuffer() { - if (device) { - BitmapDC src_dev(device, bitmap); - BitmapDC dest_dev(device, new_bitmap); -- BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY); -+ BitBlt(dest_dev, 0, 0, w, h, src_dev, 0, 0, SRCCOPY); - } else { - WindowDC wndDC(window); - BitmapDC src_dev(wndDC, bitmap); - BitmapDC dest_dev(wndDC, new_bitmap); -- BitBlt(dest_dev, 0, 0, width_, height_, src_dev, 0, 0, SRCCOPY); -+ BitBlt(dest_dev, 0, 0, w, h, src_dev, 0, 0, SRCCOPY); - } - } - -@@ -128,17 +117,17 @@ void DIBSectionBuffer::recreateBuffer() { - // Delete the old bitmap - DeleteObject(bitmap); - bitmap = 0; -- data = 0; -+ setBuffer(0, 0, NULL, 0); - } - - if (new_bitmap) { - int bpp, depth; - int redMax, greenMax, blueMax; - int redShift, greenShift, blueShift; -+ int new_stride; - - // Set up the new bitmap - bitmap = new_bitmap; -- data = new_data; - - // Determine the *actual* DIBSection format - DIBSECTION ds; -@@ -147,14 +136,16 @@ void DIBSectionBuffer::recreateBuffer() { - - // Correct the "stride" of the DIB - // *** This code DWORD aligns each row - is that right??? -- stride = width_; -- int bytesPerRow = stride * format.bpp/8; -+ new_stride = w; -+ int bytesPerRow = new_stride * format.bpp/8; - if (bytesPerRow % 4) { - bytesPerRow += 4 - (bytesPerRow % 4); -- stride = (bytesPerRow * 8) / format.bpp; -- vlog.info("adjusting DIB stride: %d to %d", width_, stride); -+ new_stride = (bytesPerRow * 8) / format.bpp; -+ vlog.info("adjusting DIB stride: %d to %d", w, new_stride); - } - -+ setBuffer(w, h, new_data, new_stride); -+ - // Calculate the PixelFormat for the DIB - bpp = depth = ds.dsBm.bmBitsPixel; - diff --git a/SOURCES/tigervnc-getmaster.patch b/SOURCES/tigervnc-getmaster.patch index 23c3d58..6ef99b4 100644 --- a/SOURCES/tigervnc-getmaster.patch +++ b/SOURCES/tigervnc-getmaster.patch @@ -1,9 +1,9 @@ diff --git a/unix/xserver/hw/vnc/InputXKB.c b/unix/xserver/hw/vnc/InputXKB.c -index a9bd11d..7b54b43 100644 +index f84a6e4..4eac939 100644 --- a/unix/xserver/hw/vnc/InputXKB.c +++ b/unix/xserver/hw/vnc/InputXKB.c -@@ -214,10 +214,7 @@ void vncPrepareInputDevices(void) - +@@ -226,10 +226,7 @@ void vncPrepareInputDevices(void) + unsigned vncGetKeyboardState(void) { - DeviceIntPtr master; @@ -12,75 +12,75 @@ index a9bd11d..7b54b43 100644 - return XkbStateFieldFromRec(&master->key->xkbInfo->state); + return XkbStateFieldFromRec(&vncKeyboardDev->master->key->xkbInfo->state); } - + unsigned vncGetLevelThreeMask(void) -@@ -238,7 +235,7 @@ unsigned vncGetLevelThreeMask(void) +@@ -250,7 +247,7 @@ unsigned vncGetLevelThreeMask(void) return 0; } - + - xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + xkb = vncKeyboardDev->master->key->xkbInfo->desc; - + act = XkbKeyActionPtr(xkb, keycode, state); if (act == NULL) -@@ -263,7 +260,7 @@ KeyCode vncPressShift(void) +@@ -275,7 +272,7 @@ KeyCode vncPressShift(void) if (state & ShiftMask) return 0; - + - xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + xkb = vncKeyboardDev->master->key->xkbInfo->desc; for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { XkbAction *act; unsigned char mask; -@@ -303,7 +300,7 @@ size_t vncReleaseShift(KeyCode *keys, size_t maxKeys) - +@@ -315,7 +312,7 @@ size_t vncReleaseShift(KeyCode *keys, size_t maxKeys) + count = 0; - + - master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); + master = vncKeyboardDev->master; xkb = master->key->xkbInfo->desc; for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { XkbAction *act; -@@ -359,7 +356,7 @@ KeyCode vncPressLevelThree(void) +@@ -371,7 +368,7 @@ KeyCode vncPressLevelThree(void) return 0; } - + - xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + xkb = vncKeyboardDev->master->key->xkbInfo->desc; - + act = XkbKeyActionPtr(xkb, keycode, state); if (act == NULL) -@@ -390,7 +387,7 @@ size_t vncReleaseLevelThree(KeyCode *keys, size_t maxKeys) - +@@ -402,7 +399,7 @@ size_t vncReleaseLevelThree(KeyCode *keys, size_t maxKeys) + count = 0; - + - master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); + master = vncKeyboardDev->master; xkb = master->key->xkbInfo->desc; for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { XkbAction *act; -@@ -433,7 +430,7 @@ KeyCode vncKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state) - if (new_state != NULL) +@@ -447,7 +444,7 @@ KeyCode vncKeysymToKeycode(KeySym keysym, unsigned state, unsigned *new_state) *new_state = state; - + + fallback = 0; - xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + xkb = vncKeyboardDev->master->key->xkbInfo->desc; for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) { unsigned int state_out; KeySym dummy; -@@ -511,7 +508,7 @@ int vncIsAffectedByNumLock(KeyCode keycode) +@@ -551,7 +548,7 @@ int vncIsAffectedByNumLock(KeyCode keycode) if (numlock_keycode == 0) return 0; - + - xkb = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc; + xkb = vncKeyboardDev->master->key->xkbInfo->desc; - + act = XkbKeyActionPtr(xkb, numlock_keycode, state); if (act == NULL) -@@ -545,7 +542,7 @@ KeyCode vncAddKeysym(KeySym keysym, unsigned state) +@@ -585,7 +582,7 @@ KeyCode vncAddKeysym(KeySym keysym, unsigned state) KeySym *syms; KeySym upper, lower; - + - master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT); + master = vncKeyboardDev->master; xkb = master->key->xkbInfo->desc; diff --git a/SOURCES/tigervnc-manpages.patch b/SOURCES/tigervnc-manpages.patch deleted file mode 100644 index 8e4b9c9..0000000 --- a/SOURCES/tigervnc-manpages.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/unix/vncserver b/unix/vncserver -index 9e7a6ac..139f960 100755 ---- a/unix/vncserver -+++ b/unix/vncserver -@@ -684,6 +684,7 @@ sub Usage - " [-geometry x]\n". - " [-pixelformat rgbNNN|bgrNNN]\n". - " [-fp ]\n". -+ " [-cc ]\n". - " [-fg]\n". - " [-autokill]\n". - " [-noxstartup]\n". -diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx -index f076565..05669a4 100644 ---- a/vncviewer/vncviewer.cxx -+++ b/vncviewer/vncviewer.cxx -@@ -352,6 +352,11 @@ static void usage(const char *programName) - " %s [parameters] -listen [port] [parameters]\n" - " %s [parameters] [.tigervnc file]\n", - programName, programName, programName); -+ fprintf(stderr,"\n" -+ "Options:\n\n" -+ " -display Xdisplay - Specifies the X display for the viewer window\n" -+ " -geometry geometry - Standard X position and sizing specification.\n"); -+ - fprintf(stderr,"\n" - "Parameters can be turned on with - or off with -=0\n" - "Parameters which take a value can be specified as " diff --git a/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch b/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch index cf9abae..7377822 100644 --- a/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch +++ b/SOURCES/tigervnc-passwd-crash-with-malloc-checks.patch @@ -1,13 +1,41 @@ +diff --git a/common/rfb/Password.cxx b/common/rfb/Password.cxx +index e4a508c..f555c57 100644 +--- a/common/rfb/Password.cxx ++++ b/common/rfb/Password.cxx +@@ -55,7 +55,7 @@ PlainPasswd::~PlainPasswd() { + + void PlainPasswd::replaceBuf(char* b) { + if (buf) +- memset(buf, 0, strlen(buf)); ++ memset(buf, 0, length ? length : strlen(buf)); + CharArray::replaceBuf(b); + } + diff --git a/common/rfb/util.h b/common/rfb/util.h -index b678b89..9e59bd3 100644 +index 3100f90..764692a 100644 --- a/common/rfb/util.h +++ b/common/rfb/util.h -@@ -50,7 +50,7 @@ namespace rfb { +@@ -51,16 +51,21 @@ namespace rfb { CharArray() : buf(0) {} CharArray(char* str) : buf(str) {} // note: assumes ownership - CharArray(int len) { -- buf = new char[len]; -+ buf = new char[len](); + CharArray(size_t len) { ++ length = len; + buf = new char[len](); } ~CharArray() { - delete [] buf; +- delete [] buf; ++ if (buf) { ++ delete [] buf; ++ buf = nullptr; ++ } + } + void format(const char *fmt, ...) __printf_attr(2, 3); + // Get the buffer pointer & clear it (i.e. caller takes ownership) + char* takeBuf() {char* tmp = buf; buf = 0; return tmp;} +- void replaceBuf(char* b) {delete [] buf; buf = b;} ++ void replaceBuf(char* b) {if (buf) delete [] buf; buf = b;} + char* buf; ++ size_t length = 0; + private: + CharArray(const CharArray&); + CharArray& operator=(const CharArray&); diff --git a/SOURCES/tigervnc-pixelformat-sanity-checks.patch b/SOURCES/tigervnc-pixelformat-sanity-checks.patch deleted file mode 100644 index 9801a5c..0000000 --- a/SOURCES/tigervnc-pixelformat-sanity-checks.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx -index 76051dc..a9d015d 100644 ---- a/common/rfb/PixelFormat.cxx -+++ b/common/rfb/PixelFormat.cxx -@@ -75,7 +75,8 @@ PixelFormat::PixelFormat(int b, int d, bool e, bool t, - redMax(rm), greenMax(gm), blueMax(bm), - redShift(rs), greenShift(gs), blueShift(bs) - { -- assert(isSane()); -+ if (!isSane()) -+ throw Exception("invalid pixel format"); - - updateState(); - } -@@ -672,8 +673,16 @@ bool PixelFormat::isSane(void) - return false; - - totalBits = bits(redMax) + bits(greenMax) + bits(blueMax); -- if (totalBits > bpp) -+ if (totalBits > depth) -+ return false; -+ -+ if ((bits(redMax) + redShift) > bpp) -+ return false; -+ if ((bits(greenMax) + greenShift) > bpp) - return false; -+ if ((bits(blueMax) + blueShift) > bpp) -+ return false; -+ - - if (((redMax << redShift) & (greenMax << greenShift)) != 0) - return false; diff --git a/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch b/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch index c4258a9..cefc769 100644 --- a/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch +++ b/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch @@ -1,5 +1,18 @@ +From 0f1ded057dbf875e69a0d72418d95610db8fa6a3 Mon Sep 17 00:00:00 2001 +From: Pierre Ossman +Date: Mon, 30 Dec 2019 10:50:52 +0100 +Subject: [PATCH] Provide correct dimensions for XShm setup + +Since 53f913a we initialize the underlying PixelBuffer with 0x0 +dimensions, which means we need to keep more explicit track of what +we are trying to allocate in the setup methods. +--- + vncviewer/PlatformPixelBuffer.cxx | 6 +++--- + vncviewer/PlatformPixelBuffer.h | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx -index 2b934c5..3d47163 100644 +index 61f7b743b..59e51d596 100644 --- a/vncviewer/PlatformPixelBuffer.cxx +++ b/vncviewer/PlatformPixelBuffer.cxx @@ -43,7 +43,7 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : @@ -11,7 +24,7 @@ index 2b934c5..3d47163 100644 xim = XCreateImage(fl_display, CopyFromParent, 32, ZPixmap, 0, 0, width, height, 32, 0); if (!xim) -@@ -139,7 +139,7 @@ static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error) +@@ -136,7 +136,7 @@ static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error) return 0; } @@ -20,7 +33,7 @@ index 2b934c5..3d47163 100644 { int major, minor; Bool pixmaps; -@@ -156,7 +156,7 @@ bool PlatformPixelBuffer::setupShm() +@@ -153,7 +153,7 @@ bool PlatformPixelBuffer::setupShm() shminfo = new XShmSegmentInfo; xim = XShmCreateImage(fl_display, CopyFromParent, 32, @@ -30,10 +43,10 @@ index 2b934c5..3d47163 100644 goto free_shminfo; diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h -index f9038cd..ec439f6 100644 +index f9038cd9c..ec439f64f 100644 --- a/vncviewer/PlatformPixelBuffer.h +++ b/vncviewer/PlatformPixelBuffer.h -@@ -53,7 +53,7 @@ protected: +@@ -53,7 +53,7 @@ class PlatformPixelBuffer: public rfb::FullFramePixelBuffer, public Surface { #if !defined(WIN32) && !defined(__APPLE__) protected: diff --git a/SOURCES/tigervnc-remove-trailing-spaces-in-user-name.patch b/SOURCES/tigervnc-remove-trailing-spaces-in-user-name.patch new file mode 100644 index 0000000..da47b03 --- /dev/null +++ b/SOURCES/tigervnc-remove-trailing-spaces-in-user-name.patch @@ -0,0 +1,26 @@ +From 989491eb4b325f980e94d27e0ad1a7bee63b6ebd Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Fri, 3 Jul 2020 13:56:35 +0200 +Subject: [PATCH] Remove trailing spaces in user name + +It's quite easy to make a mistake and add an additional space when configuring +users in the vncserver.users config file. You will then get an error that the +user doesn't exist and it's hard to spot the mistake. Same applies for a space +before the display number. +--- + unix/vncserver/vncsession-start.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/unix/vncserver/vncsession-start.in b/unix/vncserver/vncsession-start.in +index b20fcdd97..65ee0a81c 100644 +--- a/unix/vncserver/vncsession-start.in ++++ b/unix/vncserver/vncsession-start.in +@@ -33,7 +33,7 @@ fi + + DISPLAY="$1" + +-USER=`grep "^${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2-` ++USER=`grep "^ *${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2- | sed 's/ *$//g'` + + if [ -z "${USER}" ]; then + echo "No user configured for display ${DISPLAY}" >&2 diff --git a/SOURCES/tigervnc-shebang.patch b/SOURCES/tigervnc-shebang.patch deleted file mode 100644 index f76af87..0000000 --- a/SOURCES/tigervnc-shebang.patch +++ /dev/null @@ -1,9 +0,0 @@ -diff -up tigervnc-1.3.0/unix/vncserver.shebang tigervnc-1.3.0/unix/vncserver ---- tigervnc-1.3.0/unix/vncserver.shebang 2013-07-24 12:22:34.962158378 +0100 -+++ tigervnc-1.3.0/unix/vncserver 2013-07-24 12:22:41.593188190 +0100 -@@ -1,4 +1,4 @@ --#!/usr/bin/env perl -+#!/usr/bin/perl - # - # Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. - # Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. diff --git a/SOURCES/tigervnc-systemd-support.patch b/SOURCES/tigervnc-systemd-support.patch new file mode 100644 index 0000000..3b56cd8 --- /dev/null +++ b/SOURCES/tigervnc-systemd-support.patch @@ -0,0 +1,2176 @@ +From 8f09de712b53e54d15d2bd5367c10a61c57cda23 Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Wed, 6 May 2020 10:37:21 +0200 +Subject: Foo + + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 2d19b72..78eb93d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -7,6 +7,10 @@ if(POLICY CMP0022) + cmake_policy(SET CMP0022 OLD) + endif() + ++if(${CMAKE_VERSION} VERSION_LESS "3.4.0") ++ message(WARNING "CMake 3.4.0 or newer is required to get correct default installation paths") ++endif() ++ + # Internal cmake modules + set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) + +@@ -27,17 +31,16 @@ set(VERSION 1.10.1) + set(RCVERSION 1,10,1,0) + + # Installation paths +-set(BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin") +-set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share") +-set(MAN_DIR "${DATA_DIR}/man") +-set(LOCALE_DIR "${DATA_DIR}/locale") +-set(DOC_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${CMAKE_PROJECT_NAME}-${VERSION}") +- +-if(WIN32) +-set(BIN_DIR "${CMAKE_INSTALL_PREFIX}") +-set(DOC_DIR "${CMAKE_INSTALL_PREFIX}") ++include(GNUInstallDirs) ++set(CMAKE_INSTALL_UNITDIR "lib/systemd/system" CACHE PATH "systemd unit files (lib/systemd/system)") ++if(IS_ABSOLUTE "${CMAKE_INSTALL_UNITDIR}") ++ set(CMAKE_INSTALL_FULL_UNITDIR "${CMAKE_INSTALL_UNITDIR}") ++else() ++ set(CMAKE_INSTALL_FULL_UNITDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_UNITDIR}") + endif() + ++option(INSTALL_SYSTEMD_UNITS "Install TigerVNC systemd units" ON) ++ + if(MSVC) + message(FATAL_ERROR "TigerVNC cannot be built with Visual Studio. Please use MinGW") + endif() +@@ -259,8 +262,7 @@ if(ENABLE_GNUTLS) + endif() + + # Check for PAM library +-option(ENABLE_PAM "Enable PAM authentication support" ON) +-if(ENABLE_PAM) ++if(UNIX AND NOT APPLE) + check_include_files(security/pam_appl.h HAVE_PAM_H) + set(CMAKE_REQUIRED_LIBRARIES -lpam) + check_function_exists(pam_start HAVE_PAM_START) +@@ -268,10 +270,9 @@ if(ENABLE_PAM) + if(HAVE_PAM_H AND HAVE_PAM_START) + set(PAM_LIBS pam) + else() +- set(ENABLE_PAM 0) ++ message(FATAL_ERROR "Could not find PAM development files") + endif() + endif() +-set(HAVE_PAM ${ENABLE_PAM}) + + # Generate config.h and make sure the source finds it + configure_file(config.h.in config.h) +diff --git a/cmake/BuildPackages.cmake b/cmake/BuildPackages.cmake +index ec96318..1f25192 100644 +--- a/cmake/BuildPackages.cmake ++++ b/cmake/BuildPackages.cmake +@@ -86,5 +86,5 @@ endif() #UNIX + # Common + # + +-install(FILES ${CMAKE_SOURCE_DIR}/LICENCE.TXT DESTINATION ${DOC_DIR}) +-install(FILES ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${DOC_DIR}) ++install(FILES ${CMAKE_SOURCE_DIR}/LICENCE.TXT DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR}) ++install(FILES ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR}) +diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake +index e539619..793b190 100644 +--- a/cmake/StaticBuild.cmake ++++ b/cmake/StaticBuild.cmake +@@ -115,7 +115,7 @@ endif() + if(BUILD_STATIC_GCC) + # This ensures that we don't depend on libstdc++ or libgcc_s + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nodefaultlibs") +- set(STATIC_BASE_LIBRARIES "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic") ++ set(STATIC_BASE_LIBRARIES "") + if(ENABLE_ASAN AND NOT WIN32 AND NOT APPLE) + set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -Wl,-Bstatic -lasan -Wl,-Bdynamic -ldl -lm -lpthread") + endif() +@@ -135,5 +135,6 @@ if(BUILD_STATIC_GCC) + else() + set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lgcc -lgcc_eh -lc") + endif() +- set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}") ++ set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}") ++ set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic ${STATIC_BASE_LIBRARIES}") + endif() +diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt +index 8e532a2..689cdcc 100644 +--- a/common/rfb/CMakeLists.txt ++++ b/common/rfb/CMakeLists.txt +@@ -75,7 +75,7 @@ endif(WIN32) + + set(RFB_LIBRARIES ${JPEG_LIBRARIES} os rdr Xregion) + +-if(HAVE_PAM) ++if(UNIX AND NOT APPLE) + set(RFB_SOURCES ${RFB_SOURCES} UnixPasswordValidator.cxx + UnixPasswordValidator.h pam.c pam.h) + set(RFB_LIBRARIES ${RFB_LIBRARIES} ${PAM_LIBS}) +diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx +index 6f72432..f577c0d 100644 +--- a/common/rfb/SSecurityPlain.cxx ++++ b/common/rfb/SSecurityPlain.cxx +@@ -25,10 +25,10 @@ + #include + #include + #include +-#ifdef HAVE_PAM ++#if !defined(WIN32) && !defined(__APPLE__) + #include + #endif +-#ifdef BUILD_WIN ++#ifdef WIN32 + #include + #endif + +@@ -62,10 +62,10 @@ bool PasswordValidator::validUser(const char* username) + + SSecurityPlain::SSecurityPlain(SConnection* sc) : SSecurity(sc) + { +-#ifdef HAVE_PAM +- valid = new UnixPasswordValidator(); +-#elif BUILD_WIN ++#ifdef WIN32 + valid = new WinPasswdValidator(); ++#elif !defined(__APPLE__) ++ valid = new UnixPasswordValidator(); + #else + valid = NULL; + #endif +diff --git a/common/rfb/UnixPasswordValidator.cxx b/common/rfb/UnixPasswordValidator.cxx +index d096079..ee7bc0d 100644 +--- a/common/rfb/UnixPasswordValidator.cxx ++++ b/common/rfb/UnixPasswordValidator.cxx +@@ -25,9 +25,7 @@ + #include + #include + #include +-#ifdef HAVE_PAM + #include +-#endif + + using namespace rfb; + +@@ -43,10 +41,6 @@ bool UnixPasswordValidator::validateInternal(SConnection * sc, + const char *username, + const char *password) + { +-#ifdef HAVE_PAM + CharArray service(strDup(pamService.getData())); + return do_pam_auth(service.buf, username, password); +-#else +- throw AuthFailureException("PAM not supported"); +-#endif + } +diff --git a/common/rfb/pam.c b/common/rfb/pam.c +index cb067fd..acac0f4 100644 +--- a/common/rfb/pam.c ++++ b/common/rfb/pam.c +@@ -22,9 +22,6 @@ + #include + #endif + +-#ifndef HAVE_PAM +-#error "This source should not be compiled when PAM is unsupported" +-#endif + + #include + #include +diff --git a/common/rfb/pam.h b/common/rfb/pam.h +index 2688f21..d378d19 100644 +--- a/common/rfb/pam.h ++++ b/common/rfb/pam.h +@@ -21,14 +21,6 @@ + #ifndef __RFB_PAM_H__ + #define __RFB_PAM_H__ + +-#ifdef HAVE_CONFIG_H +-#include +-#endif +- +-#ifndef HAVE_PAM +-#error "This header should not be included when PAM is unsupported" +-#endif +- + #ifdef __cplusplus + extern "C" { + #endif +diff --git a/config.h.in b/config.h.in +index 2d6db9c..2d7a741 100644 +--- a/config.h.in ++++ b/config.h.in +@@ -4,10 +4,10 @@ + #cmakedefine HAVE_ACTIVE_DESKTOP_H + #cmakedefine HAVE_ACTIVE_DESKTOP_L + #cmakedefine ENABLE_NLS 1 +-#cmakedefine HAVE_PAM + +-#cmakedefine DATA_DIR "@DATA_DIR@" +-#cmakedefine LOCALE_DIR "@LOCALE_DIR@" ++#cmakedefine CMAKE_INSTALL_FULL_LIBEXECDIR "@CMAKE_INSTALL_FULL_LIBEXECDIR@" ++#cmakedefine CMAKE_INSTALL_FULL_DATADIR "@CMAKE_INSTALL_FULL_DATADIR@" ++#cmakedefine CMAKE_INSTALL_FULL_LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@" + + /* MS Visual Studio 2008 and newer doesn't know ssize_t */ + #if defined(HAVE_GNUTLS) && defined(WIN32) && !defined(__MINGW32__) +diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt +index f61e355..77ec21b 100644 +--- a/java/CMakeLists.txt ++++ b/java/CMakeLists.txt +@@ -7,8 +7,6 @@ endif() + + find_package(Java) + +-set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share") +- + set(DEFAULT_JAVACFLAGS "-source 8 -target 8 -encoding UTF-8 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann,-deprecation,-rawtypes") + set(JAVACFLAGS ${DEFAULT_JAVACFLAGS} CACHE STRING + "Java compiler flags (Default: ${DEFAULT_JAVACFLAGS})") +diff --git a/media/CMakeLists.txt b/media/CMakeLists.txt +index 256d435..088c72f 100644 +--- a/media/CMakeLists.txt ++++ b/media/CMakeLists.txt +@@ -13,11 +13,11 @@ if(CONVERT_EXECUTABLE) + if(UNIX AND NOT APPLE) + foreach(SIZE 16 22 24 32 48) + install(FILES icons/tigervnc_${SIZE}.png +- DESTINATION ${DATA_DIR}/icons/hicolor/${SIZE}x${SIZE}/apps ++ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${SIZE}x${SIZE}/apps + RENAME tigervnc.png) + endforeach() + install(FILES icons/tigervnc.svg +- DESTINATION ${DATA_DIR}/icons/hicolor/scalable/apps) ++ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps) + endif() + endif() + +diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt +index 9c8ddef..2eb10e7 100644 +--- a/po/CMakeLists.txt ++++ b/po/CMakeLists.txt +@@ -46,7 +46,7 @@ foreach(lang ${po_FILES}) + ) + + install(FILES ${mo} +- DESTINATION "${LOCALE_DIR}/${lang}/LC_MESSAGES" ++ DESTINATION "${CMAKE_INSTALL_FULL_LOCALEDIR}/${lang}/LC_MESSAGES" + RENAME tigervnc.mo + ) + +diff --git a/unix/CMakeLists.txt b/unix/CMakeLists.txt +index 7a1457d..5456e00 100644 +--- a/unix/CMakeLists.txt ++++ b/unix/CMakeLists.txt +@@ -2,7 +2,5 @@ add_subdirectory(tx) + add_subdirectory(common) + add_subdirectory(vncconfig) + add_subdirectory(vncpasswd) ++add_subdirectory(vncserver) + add_subdirectory(x0vncserver) +- +-install(PROGRAMS vncserver DESTINATION ${BIN_DIR}) +-install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1) +diff --git a/unix/vncconfig/CMakeLists.txt b/unix/vncconfig/CMakeLists.txt +index 959681f..c3823ab 100644 +--- a/unix/vncconfig/CMakeLists.txt ++++ b/unix/vncconfig/CMakeLists.txt +@@ -11,5 +11,5 @@ add_executable(vncconfig + + target_link_libraries(vncconfig tx rfb network rdr ${X11_LIBRARIES}) + +-install(TARGETS vncconfig DESTINATION ${BIN_DIR}) +-install(FILES vncconfig.man DESTINATION ${MAN_DIR}/man1 RENAME vncconfig.1) ++install(TARGETS vncconfig DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) ++install(FILES vncconfig.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncconfig.1) +diff --git a/unix/vncconfig/vncconfig.man b/unix/vncconfig/vncconfig.man +index b685a46..ed9ddda 100644 +--- a/unix/vncconfig/vncconfig.man ++++ b/unix/vncconfig/vncconfig.man +@@ -111,8 +111,8 @@ When run as a "helper" app, make the window iconified at startup. + .SH SEE ALSO + .BR vncpasswd (1), + .BR vncviewer (1), +-.BR vncserver (1), +-.BR Xvnc (1) ++.BR Xvnc (1), ++.BR vncsession (8) + .br + https://www.tigervnc.org + +diff --git a/unix/vncpasswd/CMakeLists.txt b/unix/vncpasswd/CMakeLists.txt +index a04ed0b..9f716fa 100644 +--- a/unix/vncpasswd/CMakeLists.txt ++++ b/unix/vncpasswd/CMakeLists.txt +@@ -5,5 +5,5 @@ add_executable(vncpasswd + + target_link_libraries(vncpasswd tx rfb os) + +-install(TARGETS vncpasswd DESTINATION ${BIN_DIR}) +-install(FILES vncpasswd.man DESTINATION ${MAN_DIR}/man1 RENAME vncpasswd.1) ++install(TARGETS vncpasswd DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) ++install(FILES vncpasswd.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncpasswd.1) +diff --git a/unix/vncpasswd/vncpasswd.man b/unix/vncpasswd/vncpasswd.man +index 9e68181..c70a425 100644 +--- a/unix/vncpasswd/vncpasswd.man ++++ b/unix/vncpasswd/vncpasswd.man +@@ -43,9 +43,9 @@ Default location of the VNC password file. + + .SH SEE ALSO + .BR vncviewer (1), +-.BR vncserver (1), + .BR Xvnc (1) + .BR vncconfig (1), ++.BR vncsession (8) + .br + https://www.tigervnc.org + +diff --git a/unix/vncserver.man b/unix/vncserver.man +deleted file mode 100644 +index 95f7960..0000000 +--- a/unix/vncserver.man ++++ /dev/null +@@ -1,204 +0,0 @@ +-.TH vncserver 1 "" "TigerVNC" "Virtual Network Computing" +-.SH NAME +-vncserver \- start or stop a VNC server +-.SH SYNOPSIS +-.B vncserver +-.RI [: display# ] +-.RB [ \-name +-.IR desktop-name ] +-.RB [ \-geometry +-.IR width x height ] +-.RB [ \-depth +-.IR depth ] +-.RB [ \-pixelformat +-.IR format ] +-.RB [ \-fp +-.IR font-path ] +-.RB [ \-fg ] +-.RB [ \-autokill ] +-.RB [ \-noxstartup ] +-.RB [ \-xstartup +-.IR script ] +-.RI [ Xvnc-options... ] +-.br +-.BI "vncserver \-kill :" display# +-.br +-.BI "vncserver \-list" +-.SH DESCRIPTION +-.B vncserver +-is used to start a VNC (Virtual Network Computing) desktop. +-.B vncserver +-is a Perl script which simplifies the process of starting an Xvnc server. It +-runs Xvnc with appropriate options and starts a window manager on the VNC +-desktop. +- +-.B vncserver +-can be run with no options at all. In this case it will choose the first +-available display number (usually :1), start Xvnc with that display number, +-and start the default window manager in the Xvnc session. You can also +-specify the display number, in which case vncserver will attempt to start +-Xvnc with that display number and exit if the display number is not +-available. For example: +- +-.RS +-vncserver :13 +-.RE +- +-Editing the file $HOME/.vnc/xstartup allows you to change the applications run +-at startup (but note that this will not affect an existing VNC session.) +- +-.SH OPTIONS +-You can get a list of options by passing \fB\-h\fP as an option to vncserver. +-In addition to the options listed below, any unrecognised options will be +-passed to Xvnc - see the Xvnc man page, or "Xvnc \-help", for details. +- +-.TP +-.B \-name \fIdesktop-name\fP +-Each VNC desktop has a name which may be displayed by the viewer. The desktop +-name defaults to "\fIhost\fP:\fIdisplay#\fP (\fIusername\fP)", but you can +-change it with this option. The desktop name option is passed to the xstartup +-script via the $VNCDESKTOP environment variable, which allows you to run a +-different set of applications depending on the name of the desktop. +-. +-.TP +-.B \-geometry \fIwidth\fPx\fIheight\fP +-Specify the size of the VNC desktop to be created. Default is 1024x768. +-. +-.TP +-.B \-depth \fIdepth\fP +-Specify the pixel depth (in bits) of the VNC desktop to be created. Default is +-24. Other possible values are 8, 15 and 16 - anything else is likely to cause +-strange behaviour by applications. +-. +-.TP +-.B \-pixelformat \fIformat\fP +-Specify pixel format for Xvnc to use (BGRnnn or RGBnnn). The default for +-depth 8 is BGR233 (meaning the most significant two bits represent blue, the +-next three green, and the least significant three represent red), the default +-for depth 16 is RGB565, and the default for depth 24 is RGB888. +-. +-.TP +-.B \-cc 3 +-As an alternative to the default TrueColor visual, this allows you to run an +-Xvnc server with a PseudoColor visual (i.e. one which uses a color map or +-palette), which can be useful for running some old X applications which only +-work on such a display. Values other than 3 (PseudoColor) and 4 (TrueColor) +-for the \-cc option may result in strange behaviour, and PseudoColor desktops +-must have an 8-bit depth. +-. +-.TP +-.B \-kill :\fIdisplay#\fP +-This kills a VNC desktop previously started with vncserver. It does this by +-killing the Xvnc process, whose process ID is stored in the file +-"$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid". The +-.B \-kill +-option ignores anything preceding the first colon (":") in the display +-argument. Thus, you can invoke "vncserver \-kill $DISPLAY", for example at the +-end of your xstartup file after a particular application exits. +-. +-.TP +-.B \-fp \fIfont-path\fP +-If the vncserver script detects that the X Font Server (XFS) is running, it +-will attempt to start Xvnc and configure Xvnc to use XFS for font handling. +-Otherwise, if XFS is not running, the vncserver script will attempt to start +-Xvnc and allow Xvnc to use its own preferred method of font handling (which may +-be a hard-coded font path or, on more recent systems, a font catalog.) In +-any case, if Xvnc fails to start, the vncserver script will then attempt to +-determine an appropriate X font path for this system and start Xvnc using +-that font path. +- +-The +-.B \-fp +-argument allows you to override the above fallback logic and specify a font +-path for Xvnc to use. +-. +-.TP +-.B \-fg +-Runs Xvnc as a foreground process. This has two effects: (1) The VNC server +-can be aborted with CTRL-C, and (2) the VNC server will exit as soon as the +-user logs out of the window manager in the VNC session. This may be necessary +-when launching TigerVNC from within certain grid computing environments. +-. +-.TP +-.B \-autokill +-Automatically kill Xvnc whenever the xstartup script exits. In most cases, +-this has the effect of terminating Xvnc when the user logs out of the window +-manager. +-. +-.TP +-.B \-noxstartup +-Do not run the %HOME/.vnc/xstartup script after launching Xvnc. This +-option allows you to manually start a window manager in your TigerVNC session. +-. +-.TP +-.B \-xstartup \fIscript\fP +-Run a custom startup script, instead of %HOME/.vnc/xstartup, after launching +-Xvnc. This is useful to run full-screen applications. +-. +-.TP +-.B \-list +-Lists all VNC desktops started by vncserver. +- +-.SH FILES +-Several VNC-related files are found in the directory $HOME/.vnc: +-.TP +-$HOME/.vnc/xstartup +-A shell script specifying X applications to be run when a VNC desktop is +-started. If this file does not exist, then vncserver will create a default +-xstartup script which attempts to launch your chosen window manager. +-.TP +-/etc/tigervnc/vncserver-config-defaults +-The optional system-wide equivalent of $HOME/.vnc/config. If this file exists +-and defines options to be passed to Xvnc, they will be used as defaults for +-users. The user's $HOME/.vnc/config overrides settings configured in this file. +-The overall configuration file load order is: this file, $HOME/.vnc/config, +-and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist. +-.TP +-/etc/tigervnc/vncserver-config-mandatory +-The optional system-wide equivalent of $HOME/.vnc/config. If this file exists +-and defines options to be passed to Xvnc, they will override any of the same +-options defined in a user's $HOME/.vnc/config. This file offers a mechanism +-to establish some basic form of system-wide policy. WARNING! There is +-nothing stopping users from constructing their own vncserver-like script +-that calls Xvnc directly to bypass any options defined in +-/etc/tigervnc/vncserver-config-mandatory. Likewise, any CLI arguments passed +-to vncserver will override ANY config file setting of the same name. The +-overall configuration file load order is: +-/etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then this file. +-None are required to exist. +-.TP +-$HOME/.vnc/config +-An optional server config file wherein options to be passed to Xvnc are listed +-to avoid hard-coding them to the physical invocation. List options in this file +-one per line. For those requiring an argument, simply separate the option from +-the argument with an equal sign, for example: "geometry=2000x1200" or +-"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed +-as a single word, for example: "localhost" or "alwaysshared". +-.TP +-$HOME/.vnc/passwd +-The VNC password file. +-.TP +-$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log +-The log file for Xvnc and applications started in xstartup. +-.TP +-$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid +-Identifies the Xvnc process ID, used by the +-.B \-kill +-option. +- +-.SH SEE ALSO +-.BR vncviewer (1), +-.BR vncpasswd (1), +-.BR vncconfig (1), +-.BR Xvnc (1) +-.br +-https://www.tigervnc.org +- +-.SH AUTHOR +-Tristan Richardson, RealVNC Ltd., D. R. Commander and others. +- +-VNC was originally developed by the RealVNC team while at Olivetti +-Research Ltd / AT&T Laboratories Cambridge. TightVNC additions were +-implemented by Constantin Kaplinsky. Many other people have since +-participated in development, testing and support. This manual is part +-of the TigerVNC software suite. +diff --git a/unix/vncserver/CMakeLists.txt b/unix/vncserver/CMakeLists.txt +new file mode 100644 +index 0000000..eeb4b7b +--- /dev/null ++++ b/unix/vncserver/CMakeLists.txt +@@ -0,0 +1,20 @@ ++add_executable(vncsession vncsession.c) ++target_link_libraries(vncsession ${PAM_LIBS}) ++ ++configure_file(vncserver@.service.in vncserver@.service @ONLY) ++configure_file(vncsession-start.in vncsession-start @ONLY) ++configure_file(vncserver.in vncserver @ONLY) ++ ++install(TARGETS vncsession DESTINATION ${CMAKE_INSTALL_FULL_SBINDIR}) ++install(FILES tigervnc.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME tigervnc) ++install(FILES vncsession.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8 RENAME vncsession.8) ++install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncserver DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}) ++install(FILES vncserver.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8 RENAME vncserver.8) ++install(FILES vncserver-config-defaults vncserver-config-mandatory DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tigervnc) ++ ++install(FILES vncserver.users DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tigervnc) ++ ++if(INSTALL_SYSTEMD_UNITS) ++ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncserver@.service DESTINATION ${CMAKE_INSTALL_FULL_UNITDIR}) ++ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncsession-start DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}) ++endif() +diff --git a/unix/vncserver/selinux/Makefile b/unix/vncserver/selinux/Makefile +new file mode 100644 +index 0000000..904a2d5 +--- /dev/null ++++ b/unix/vncserver/selinux/Makefile +@@ -0,0 +1,24 @@ ++# SELinux module for TigerVNC's vncsession ++# ++# This will install the policy module, but not load it. To apply ++# it you should also run: ++# ++# sudo semodule -i /usr/share/selinux/packages/vncsession.pp ++# sudo restorecon /usr/sbin/vncsession /usr/libexec/vncsession-start ++# ++ ++PREFIX=/usr ++DATADIR=$(PREFIX)/share ++ ++all: vncsession.pp ++ ++%.pp: %.te ++ make -f $(DATADIR)/selinux/devel/Makefile $@ ++ ++clean: ++ rm -f *.pp ++ rm -rf tmp ++ ++install: vncsession.pp ++ mkdir -p $(DESTDIR)$(DATADIR)/selinux/packages ++ install vncsession.pp $(DESTDIR)$(DATADIR)/selinux/packages/vncsession.pp +diff --git a/unix/vncserver/selinux/vncsession.fc b/unix/vncserver/selinux/vncsession.fc +new file mode 100644 +index 0000000..121cdd2 +--- /dev/null ++++ b/unix/vncserver/selinux/vncsession.fc +@@ -0,0 +1,26 @@ ++# ++# Copyright 2018 Pierre Ossman for Cendio AB ++# ++# This is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This software is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this software; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++# USA. ++# ++ ++HOME_DIR/\.vnc(/.*)? gen_context(system_u:object_r:xdm_home_t,s0) ++HOME_ROOT/\.vnc(/.*)? gen_context(system_u:object_r:xdm_home_t,s0) ++ ++/usr/sbin/vncsession -- gen_context(system_u:object_r:vnc_session_exec_t,s0) ++/usr/libexec/vncsession-start -- gen_context(system_u:object_r:vnc_session_exec_t,s0) ++ ++/var/run/vncsession-:[0-9]*\.pid -- gen_context(system_u:object_r:vnc_session_var_run_t,s0) +diff --git a/unix/vncserver/selinux/vncsession.if b/unix/vncserver/selinux/vncsession.if +new file mode 100644 +index 0000000..3eb6a30 +--- /dev/null ++++ b/unix/vncserver/selinux/vncsession.if +@@ -0,0 +1 @@ ++## +diff --git a/unix/vncserver/selinux/vncsession.te b/unix/vncserver/selinux/vncsession.te +new file mode 100644 +index 0000000..941f28d +--- /dev/null ++++ b/unix/vncserver/selinux/vncsession.te +@@ -0,0 +1,67 @@ ++# ++# Copyright 2018-2020 Pierre Ossman for Cendio AB ++# ++# This is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This software is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this software; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++# USA. ++# ++ ++policy_module(vncsession, 1.0.0); ++ ++gen_require(` ++ type unconfined_t; ++ type xdm_home_t; ++') ++ ++type vnc_session_exec_t; ++corecmd_executable_file(vnc_session_exec_t) ++type vnc_session_t; ++init_daemon_domain(vnc_session_t, vnc_session_exec_t) ++auth_login_pgm_domain(vnc_session_t) ++ ++type vnc_session_var_run_t; ++files_pid_file(vnc_session_var_run_t) ++allow vnc_session_t vnc_session_var_run_t:file manage_file_perms; ++files_pid_filetrans(vnc_session_t, vnc_session_var_run_t, file) ++ ++auth_write_login_records(vnc_session_t) ++ ++can_exec(vnc_session_t, vnc_session_exec_t) ++ ++userdom_spec_domtrans_all_users(vnc_session_t) ++userdom_signal_all_users(vnc_session_t) ++ ++allow vnc_session_t self:capability { kill chown dac_override dac_read_search fowner setgid setuid sys_resource }; ++allow vnc_session_t self:process { getcap setsched setexec setrlimit }; ++allow vnc_session_t self:fifo_file rw_fifo_file_perms; ++ ++manage_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) ++manage_fifo_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) ++manage_sock_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) ++manage_lnk_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) ++ ++userdom_user_home_dir_filetrans(unconfined_t, xdm_home_t, dir, ".vnc") ++userdom_user_home_dir_filetrans(vnc_session_t, xdm_home_t, dir, ".vnc") ++ ++userdom_admin_home_dir_filetrans(vnc_session_t, xdm_home_t, dir, ".vnc") ++userdom_admin_home_dir_filetrans(unconfined_t, xdm_home_t, dir, ".vnc") ++ ++miscfiles_read_localization(vnc_session_t) ++ ++kernel_read_kernel_sysctls(vnc_session_t) ++ ++logging_append_all_logs(vnc_session_t) ++ ++mcs_process_set_categories(vnc_session_t) ++mcs_killall(vnc_session_t) +diff --git a/unix/vncserver/tigervnc.pam b/unix/vncserver/tigervnc.pam +new file mode 100644 +index 0000000..0f4cb3a +--- /dev/null ++++ b/unix/vncserver/tigervnc.pam +@@ -0,0 +1,11 @@ ++#%PAM-1.0 ++# pam_selinux.so close should be the first session rule ++-session required pam_selinux.so close ++session required pam_loginuid.so ++-session required pam_selinux.so open ++session required pam_namespace.so ++session optional pam_keyinit.so force revoke ++session required pam_limits.so ++-session optional pam_systemd.so ++session required pam_unix.so ++-session optional pam_reauthorize.so prepare +diff --git a/unix/vncserver/vncserver-config-defaults b/unix/vncserver/vncserver-config-defaults +new file mode 100644 +index 0000000..0c217bf +--- /dev/null ++++ b/unix/vncserver/vncserver-config-defaults +@@ -0,0 +1,15 @@ ++## Default settings for VNC servers started by the vncserver service ++# ++# Any settings given here will override the builtin defaults, but can ++# also be overriden by ~/.vnc/config and vncserver-config-mandatory. ++# ++# See the following manpages for more details: vncserver(1) Xvnc(1) ++# ++# Several common settings are shown below. Uncomment and modify to your ++# liking. ++ ++# securitytypes=vncauth,tlsvnc ++# desktop=sandbox ++# geometry=2000x1200 ++# localhost ++# alwaysshared +diff --git a/unix/vncserver/vncserver-config-mandatory b/unix/vncserver/vncserver-config-mandatory +new file mode 100644 +index 0000000..98c32f6 +--- /dev/null ++++ b/unix/vncserver/vncserver-config-mandatory +@@ -0,0 +1,15 @@ ++## Mandatory settings for VNC servers started by the vncserver service ++# ++# Any settings given here will override the builtin defaults and ++# settings specified in ~/.vnc/config or vnc-config-defaults. ++# ++# See the following manpages for more details: vncserver(1) Xvnc(1) ++# ++# Several common settings are shown below. Uncomment and modify to your ++# liking. ++ ++# securitytypes=vncauth,tlsvnc ++# desktop=sandbox ++# geometry=2000x1200 ++# localhost ++# alwaysshared +diff --git a/unix/vncserver/vncserver.in b/unix/vncserver/vncserver.in +new file mode 100755 +index 0000000..8e05b72 +--- /dev/null ++++ b/unix/vncserver/vncserver.in +@@ -0,0 +1,485 @@ ++#!/usr/bin/perl ++# ++# Copyright (C) 2015-2019 Pierre Ossman for Cendio AB ++# Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. ++# Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. ++# Copyright (C) 2002-2003 Constantin Kaplinsky. All Rights Reserved. ++# Copyright (C) 2002-2005 RealVNC Ltd. ++# Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. ++# ++# This is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This software is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this software; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++# USA. ++# ++ ++# ++# vncserver - wrapper script to start an X VNC server. ++# ++ ++&SanityCheck(); ++ ++# ++# Global variables. You may want to configure some of these for ++# your site ++# ++ ++$vncUserDir = "$ENV{HOME}/.vnc"; ++$vncUserConfig = "$vncUserDir/config"; ++ ++$vncSystemConfigDir = "/etc/tigervnc"; ++$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults"; ++$vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory"; ++ ++$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority"; ++ ++chop($host = `uname -n`); ++ ++if (-d "/etc/X11/fontpath.d") { ++ $fontPath = "catalogue:/etc/X11/fontpath.d"; ++} ++ ++@fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/'); ++if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');} ++if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');} ++if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');} ++push(@fontpaths, '/usr/share/fonts/default'); ++ ++@fonttypes = ('misc', ++ '75dpi', ++ '100dpi', ++ 'Speedo', ++ 'Type1'); ++ ++foreach $_fpath (@fontpaths) { ++ foreach $_ftype (@fonttypes) { ++ if (-f "$_fpath/$_ftype/fonts.dir") { ++ if (! -l "$_fpath/$_ftype") { ++ $defFontPath .= "$_fpath/$_ftype,"; ++ } ++ } ++ } ++} ++ ++if ($defFontPath) { ++ if (substr($defFontPath, -1, 1) == ',') { ++ chop $defFontPath; ++ } ++} ++ ++if ($fontPath eq "") { ++ $fontPath = $defFontPath; ++} ++ ++# Find display number. ++if ((@ARGV == 1) && ($ARGV[0] =~ /^:(\d+)$/)) { ++ $displayNumber = $1; ++ if (!&CheckDisplayNumber($displayNumber)) { ++ die "A VNC server is already running as :$displayNumber\n"; ++ } ++} else { ++ &Usage(); ++} ++ ++$vncPort = 5900 + $displayNumber; ++ ++$desktopName = "$host:$displayNumber ($ENV{USER})"; ++ ++my %default_opts; ++my %config; ++ ++# We set some reasonable defaults. Config file settings ++# override these where present. ++$default_opts{desktop} = $desktopName; ++$default_opts{auth} = $xauthorityFile; ++$default_opts{rfbwait} = 30000; ++$default_opts{rfbauth} = "$vncUserDir/passwd"; ++$default_opts{rfbport} = $vncPort; ++$default_opts{fp} = $fontPath if ($fontPath); ++$default_opts{pn} = ""; ++ ++# Load user-overrideable system defaults ++LoadConfig($vncSystemConfigDefaultsFile); ++ ++# Then the user's settings ++LoadConfig($vncUserConfig); ++ ++# And then override anything set above if mandatory settings exist. ++# WARNING: "Mandatory" is used loosely here! As the man page says, ++# there is nothing stopping someone from EASILY subverting the ++# settings in $vncSystemConfigMandatoryFile by simply passing ++# CLI args to vncserver, which trump config files! To properly ++# hard force policy in a non-subvertible way would require major ++# development work that touches Xvnc itself. ++LoadConfig($vncSystemConfigMandatoryFile, 1); ++ ++# ++# Check whether VNC authentication is enabled, and if so, check that ++# a VNC password has been created. ++# ++ ++$securityTypeArgSpecified = 0; ++$vncAuthEnabled = 0; ++$passwordArgSpecified = 0; ++@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc"); ++ ++# ...first we check our configuration files' settings ++if ($config{'securitytypes'}) { ++ $securityTypeArgSpecified = 1; ++ foreach $arg2 (split(',', $config{'securitytypes'})) { ++ if (grep {$_ eq lc($arg2)} @vncAuthStrings) { ++ $vncAuthEnabled = 1; ++ } ++ } ++} ++ ++if ($config{'password'} || ++ $config{'passwordfile'} || ++ $config{'rfbauth'}) { ++ $passwordArgSpecified = 1; ++} ++ ++if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { ++ ($z,$z,$mode) = stat("$vncUserDir/passwd"); ++ if (!(-e "$vncUserDir/passwd") || ($mode & 077)) { ++ die "VNC authentication enabled, but no password file created.\n"; ++ } ++} ++ ++# ++# Find a desktop session to run ++# ++ ++my $sessionname; ++my %session; ++ ++$sessionname = delete $config{'session'}; ++ ++if ($sessionname) { ++ %session = LoadXSession($sessionname); ++ if (!%session) { ++ warn "Could not load configured desktop session $sessionname\n"; ++ $sessionname = undef; ++ } ++} ++ ++if (!$sessionname) { ++ foreach $file (glob("/usr/share/xsessions/*.desktop")) { ++ ($name) = $file =~ /^.*\/(.*)[.]desktop$/; ++ %session = LoadXSession($name); ++ if (%session) { ++ $sessionname = $name; ++ last; ++ } ++ } ++} ++ ++if (!$sessionname) { ++ die "Could not find a desktop session to run\n"; ++} ++ ++warn "Using desktop session $sessionname\n"; ++ ++if (!$session{'Exec'}) { ++ die "No command specified for desktop session\n"; ++} ++ ++$ENV{GDMSESSION} = $sessionname; ++$ENV{DESKTOP_SESSION} = $sessionname; ++$ENV{XDG_SESSION_DESKTOP} = $sessionname; ++ ++if ($session{'DesktopNames'}) { ++ $ENV{XDG_DESKTOP_NAMES} = $session{'DesktopNames'} =~ s/;/:/gr; ++} ++ ++ ++# Make an X server cookie and set up the Xauthority file ++# mcookie is a part of util-linux, usually only GNU/Linux systems have it. ++$cookie = `mcookie`; ++# Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it, ++# otherwise use perl's random number generator, seeded with the sum ++# of the current time, our PID and part of the encrypted form of the password. ++if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) { ++ my $randata; ++ if (sysread(URANDOM, $randata, 16) == 16) { ++ $cookie = unpack 'h*', $randata; ++ } ++ close(URANDOM); ++} ++if ($cookie eq "") { ++ srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); ++ for (1..16) { ++ $cookie .= sprintf("%02x", int(rand(256)) % 256); ++ } ++} ++ ++open(XAUTH, "|xauth -f $xauthorityFile source -"); ++print XAUTH "add $host:$displayNumber . $cookie\n"; ++print XAUTH "add $host/unix:$displayNumber . $cookie\n"; ++close(XAUTH); ++ ++$ENV{XAUTHORITY} = $xauthorityFile; ++ ++# Now start the X VNC Server ++ ++@cmd = ("xinit"); ++ ++push(@cmd, $Xsession, $session{'Exec'}); ++ ++push(@cmd, '--'); ++ ++ ++# We build up our Xvnc command with options ++push(@cmd, "@CMAKE_INSTALL_FULL_BINDIR@/Xvnc", ":$displayNumber"); ++ ++foreach my $k (sort keys %config) { ++ push(@cmd, "-$k"); ++ push(@cmd, $config{$k}) if $config{$k}; ++ delete $default_opts{$k}; # file options take precedence ++} ++ ++foreach my $k (sort keys %default_opts) { ++ push(@cmd, "-$k"); ++ push(@cmd, $default_opts{$k}) if $default_opts{$k}; ++} ++ ++warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n"; ++ ++warn "Starting desktop session $sessionname\n"; ++ ++exec(@cmd); ++ ++die "Failed to start session.\n"; ++ ++############################################################################### ++# Functions ++############################################################################### ++ ++# ++# Populate the global %config hash with settings from a specified ++# vncserver configuration file if it exists ++# ++# Args: 1. file path ++# 2. optional boolean flag to enable warning when a previously ++# set configuration setting is being overridden ++# ++sub LoadConfig { ++ local ($configFile, $warnoverride) = @_; ++ local ($toggle) = undef; ++ ++ if (stat($configFile)) { ++ if (open(IN, $configFile)) { ++ while () { ++ next if /^#/; ++ if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) { ++ $k = lc($k); # must normalize key case ++ if ($warnoverride && $config{$k}) { ++ print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n"); ++ } ++ $config{$k} = $v; ++ } elsif ($_ =~ m/^\s*(\S+)/) { ++ # We can't reasonably warn on override of toggles (e.g. AlwaysShared) ++ # because it would get crazy to do so. We'd have to check if the ++ # current config file being loaded defined the logical opposite setting ++ # (NeverShared vs. AlwaysShared, etc etc). ++ $toggle = lc($1); # must normalize key case ++ $config{$toggle} = $k; ++ } ++ } ++ close(IN); ++ } ++ } ++} ++ ++ ++# ++# Load a session desktop file ++# ++sub LoadXSession { ++ local ($name) = @_; ++ my $file, $found_group, %session; ++ ++ $file = "/usr/share/xsessions/$name.desktop"; ++ ++ if (!stat($file)) { ++ warn "Could not find session desktop file $file"; ++ return; ++ } ++ ++ if (!open(IN, $file)) { ++ warn "Could not open session desktop file $file"; ++ return; ++ } ++ ++ $found_group = 0; ++ while (my $line = ) { ++ next if $line =~ /^#/; ++ next if $line =~ /^\s*$/; ++ ++ if (!$found_group) { ++ next if $line != "[Desktop Entry]"; ++ $found_group = 1; ++ next; ++ } else { ++ last if $line =~ /^\[/; ++ } ++ ++ my ($key, $value) = $line =~ /^\s*([]A-Za-z0-9_@\-\[]+)\s*=\s*(.*)$/; ++ if (!$key) { ++ warn "Invalid session desktop file $file"; ++ close(IN); ++ return; ++ } ++ ++ $value =~ s/\\s/ /g; ++ $value =~ s/\\n/\n/g; ++ $value =~ s/\\t/\t/g; ++ $value =~ s/\\r/\r/g; ++ $value =~ s/\\\\/\\/g; ++ ++ $session{$key} = $value; ++ } ++ ++ close(IN); ++ ++ return %session; ++} ++ ++ ++# ++# CheckDisplayNumber checks if the given display number is available. A ++# display number n is taken if something is listening on the VNC server port ++# (5900+n) or the X server port (6000+n). ++# ++ ++sub CheckDisplayNumber ++{ ++ local ($n) = @_; ++ ++ socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; ++ eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; ++ if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) { ++ close(S); ++ return 0; ++ } ++ close(S); ++ ++ socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; ++ eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; ++ if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) { ++ close(S); ++ return 0; ++ } ++ close(S); ++ ++ if (-e "/tmp/.X$n-lock") { ++ warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n"; ++ warn "Remove this file if there is no X server $host:$n\n"; ++ return 0; ++ } ++ ++ if (-e "/tmp/.X11-unix/X$n") { ++ warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n"; ++ warn "Remove this file if there is no X server $host:$n\n"; ++ return 0; ++ } ++ ++ if (-e "/usr/spool/sockets/X11/$n") { ++ warn("\nWarning: $host:$n is taken because of ". ++ "/usr/spool/sockets/X11/$n\n"); ++ warn "Remove this file if there is no X server $host:$n\n"; ++ return 0; ++ } ++ ++ return 1; ++} ++ ++# ++# Usage ++# ++ ++sub Usage ++{ ++ die("\nusage: $prog \n\n"); ++} ++ ++ ++# Routine to make sure we're operating in a sane environment. ++sub SanityCheck ++{ ++ local ($cmd); ++ ++ # Get the program name ++ ($prog) = ($0 =~ m|([^/]+)$|); ++ ++ # ++ # Check we have all the commands we'll need on the path. ++ # ++ ++ cmd: ++ foreach $cmd ("uname","xauth","xinit") { ++ for (split(/:/,$ENV{PATH})) { ++ if (-x "$_/$cmd") { ++ next cmd; ++ } ++ } ++ die "$prog: couldn't find \"$cmd\" on your PATH.\n"; ++ } ++ ++ foreach $cmd ("/etc/X11/xinit/Xsession", "/etc/X11/Xsession") { ++ if (-x "$cmd") { ++ $Xsession = $cmd; ++ last; ++ } ++ } ++ if (not defined $Xsession) { ++ die "$prog: Couldn't find suitable Xsession.\n"; ++ } ++ ++ ++ if (!defined($ENV{HOME})) { ++ die "$prog: The HOME environment variable is not set.\n"; ++ } ++ ++ # ++ # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an ++ # eval, and if it fails we try 'require "sys/socket.ph"'. If this fails, ++ # we just guess at the values. If you find perl moaning here, just ++ # hard-code the values of AF_INET and SOCK_STREAM. You can find these out ++ # for your platform by looking in /usr/include/sys/socket.h and related ++ # files. ++ # ++ ++ chop($os = `uname`); ++ chop($osrev = `uname -r`); ++ ++ eval 'use Socket'; ++ if ($@) { ++ eval 'require "sys/socket.ph"'; ++ if ($@) { ++ if (($os eq "SunOS") && ($osrev !~ /^4/)) { ++ $AF_INET = 2; ++ $SOCK_STREAM = 2; ++ } else { ++ $AF_INET = 2; ++ $SOCK_STREAM = 1; ++ } ++ } else { ++ $AF_INET = &AF_INET; ++ $SOCK_STREAM = &SOCK_STREAM; ++ } ++ } else { ++ $AF_INET = &AF_INET; ++ $SOCK_STREAM = &SOCK_STREAM; ++ } ++} +diff --git a/unix/vncserver/vncserver.man b/unix/vncserver/vncserver.man +new file mode 100644 +index 0000000..f1017be +--- /dev/null ++++ b/unix/vncserver/vncserver.man +@@ -0,0 +1 @@ ++.so man8/vncsession.8 +diff --git a/unix/vncserver/vncserver.users b/unix/vncserver/vncserver.users +new file mode 100644 +index 0000000..24875c8 +--- /dev/null ++++ b/unix/vncserver/vncserver.users +@@ -0,0 +1,8 @@ ++# TigerVNC User assignment ++# ++# This file assigns users to specific VNC display numbers. ++# The syntax is =. E.g.: ++# ++# :2=andrew ++# :3=lisa ++ +diff --git a/unix/vncserver/vncserver@.service.in b/unix/vncserver/vncserver@.service.in +new file mode 100644 +index 0000000..584ecf4 +--- /dev/null ++++ b/unix/vncserver/vncserver@.service.in +@@ -0,0 +1,43 @@ ++# The vncserver service unit file ++# ++# Quick HowTo: ++# 1. Add a user mapping to /etc/tigervnc/vncserver.users. ++# 2. Adjust the global or user configuration. See the ++# vncsession(8) manpage for details. (OPTIONAL) ++# 3. Run `systemctl enable vncserver@:.service` ++# 4. Run `systemctl start vncserver@:.service` ++# ++# DO NOT RUN THIS SERVICE if your local area network is ++# untrusted! For a secure way of using VNC, you should ++# limit connections to the local host and then tunnel from ++# the machine you want to view VNC on (host A) to the machine ++# whose VNC output you want to view (host B) ++# ++# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB ++# ++# this will open a connection on port 590N of your hostA to hostB's port 590M ++# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). ++# See the ssh man page for details on port forwarding) ++# ++# You can then point a VNC client on hostA at vncdisplay N of localhost and with ++# the help of ssh, you end up seeing what hostB makes available on port 590M ++# ++# Use "nolisten=tcp" to prevent X connections to your VNC server via TCP. ++# ++# Use "localhost" to prevent remote VNC clients connecting except when ++# doing so through a secure tunnel. See the "-via" option in the ++# `man vncviewer' manual page. ++ ++ ++[Unit] ++Description=Remote desktop service (VNC) ++After=syslog.target network.target ++ ++[Service] ++Type=forking ++ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-start %i ++PIDFile=/var/run/vncsession-%i.pid ++SELinuxContext=system_u:system_r:vnc_session_t:s0 ++ ++[Install] ++WantedBy=multi-user.target +diff --git a/unix/vncserver/vncsession-start.in b/unix/vncserver/vncsession-start.in +new file mode 100644 +index 0000000..b20fcdd +--- /dev/null ++++ b/unix/vncserver/vncsession-start.in +@@ -0,0 +1,43 @@ ++#!/bin/bash ++# ++# Copyright 2019 Pierre Ossman for Cendio AB ++# ++# This is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This software is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this software; if not, write to the Free Software ++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++# USA. ++# ++ ++USERSFILE="@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver.users" ++ ++if [ $# -ne 1 ]; then ++ echo "Syntax:" >&2 ++ echo " $0 " >&2 ++ exit 1 ++fi ++ ++if [ ! -f "${USERSFILE}" ]; then ++ echo "Users file ${USERSFILE} missing" >&2 ++ exit 1 ++fi ++ ++DISPLAY="$1" ++ ++USER=`grep "^${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2-` ++ ++if [ -z "${USER}" ]; then ++ echo "No user configured for display ${DISPLAY}" >&2 ++ exit 1 ++fi ++ ++exec "@CMAKE_INSTALL_FULL_SBINDIR@/vncsession" "${USER}" "${DISPLAY}" +diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c +new file mode 100644 +index 0000000..21a40f6 +--- /dev/null ++++ b/unix/vncserver/vncsession.c +@@ -0,0 +1,592 @@ ++/* ++ * Copyright 2018 Pierre Ossman for Cendio AB ++ * ++ * This is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This software is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this software; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++ * USA. ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern char **environ; ++ ++// PAM service name ++const char *SERVICE_NAME = "tigervnc"; ++ ++// Main script PID ++volatile static pid_t script = -1; ++ ++// Daemon completion pipe ++int daemon_pipe_fd = -1; ++ ++static int ++begin_daemon(void) ++{ ++ int devnull, fds[2]; ++ pid_t pid; ++ ++ /* Pipe to report startup success */ ++ if (pipe(fds) < 0) { ++ perror("pipe"); ++ return -1; ++ } ++ ++ /* First fork */ ++ pid = fork(); ++ if (pid < 0) { ++ perror("fork"); ++ return -1; ++ } ++ ++ if (pid != 0) { ++ ssize_t len; ++ char buf[1]; ++ ++ close(fds[1]); ++ ++ /* Wait for child to finish startup */ ++ len = read(fds[0], buf, 1); ++ if (len != 1) { ++ fprintf(stderr, "Failure daemonizing\n"); ++ _exit(EX_OSERR); ++ } ++ ++ _exit(0); ++ } ++ ++ close(fds[0]); ++ daemon_pipe_fd = fds[1]; ++ ++ /* Detach from terminal */ ++ if (setsid() < 0) { ++ perror("setsid"); ++ return -1; ++ } ++ ++ /* Another fork required to fully detach */ ++ pid = fork(); ++ if (pid < 0) { ++ perror("fork"); ++ return -1; ++ } ++ ++ if (pid == 0) ++ _exit(0); ++ ++ /* Send all stdio to /dev/null */ ++ devnull = open("/dev/null", O_RDWR); ++ if (devnull < 0) { ++ fprintf(stderr, "Failed to open /dev/null: %s\n", strerror(errno)); ++ return -1; ++ } ++ if ((dup2(devnull, 0) < 0) || ++ (dup2(devnull, 1) < 0) || ++ (dup2(devnull, 2) < 0)) { ++ perror("dup2"); ++ return -1; ++ } ++ if (devnull > 2) ++ close(devnull); ++ ++ /* Full control of access bits */ ++ umask(0); ++ ++ /* A safe working directory */ ++ if (chdir("/") < 0) { ++ perror("chdir"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void ++finish_daemon(void) ++{ ++ write(daemon_pipe_fd, "+", 1); ++ close(daemon_pipe_fd); ++ daemon_pipe_fd = -1; ++} ++ ++static void ++sighandler(int sig) ++{ ++ if (script > 0) { ++ kill(script, SIGTERM); ++ } ++} ++ ++static void ++setup_signals(void) ++{ ++ struct sigaction act; ++ ++ memset(&act, 0, sizeof(act)); ++ act.sa_handler = sighandler; ++ sigemptyset(&act.sa_mask); ++ act.sa_flags = 0; ++ ++ sigaction(SIGHUP, &act, NULL); ++ sigaction(SIGINT, &act, NULL); ++ sigaction(SIGTERM, &act, NULL); ++ sigaction(SIGQUIT, &act, NULL); ++ sigaction(SIGPIPE, &act, NULL); ++} ++ ++static int ++conv(int num_msg, ++ const struct pam_message **msg, ++ struct pam_response **resp, void *appdata_ptr) ++{ ++ /* Opening a session should not require a conversation */ ++ return PAM_CONV_ERR; ++} ++ ++static pam_handle_t * ++run_pam(int *pamret, const char *username, const char *display) ++{ ++ pam_handle_t *pamh; ++ ++ /* Say hello to PAM */ ++ struct pam_conv pconv; ++ pconv.conv = conv; ++ pconv.appdata_ptr = NULL; ++ *pamret = pam_start(SERVICE_NAME, username, &pconv, &pamh); ++ if (*pamret != PAM_SUCCESS) { ++ /* pam_strerror requires a pamh argument, but if pam_start ++ fails, pamh is invalid. In practice, at least the Linux ++ implementation of pam_strerror does not use the pamh ++ argument, but let's take care - avoid pam_strerror here. */ ++ syslog(LOG_CRIT, "pam_start failed: %d", *pamret); ++ return NULL; ++ } ++ ++ /* ConsoleKit and systemd (and possibly others) uses this to ++ determine if the session is local or not. It needs to be set to ++ something that can't be interpreted as localhost. We don't know ++ what the client's address is though, and that might change on ++ reconnects. We also don't want to set it to some text string as ++ that results in a DNS lookup with e.g. libaudit. Let's use a ++ fake IPv4 address from the documentation range. */ ++ /* FIXME: This might throw an error on a IPv6-only host */ ++ *pamret = pam_set_item(pamh, PAM_RHOST, "203.0.113.20"); ++ if (*pamret != PAM_SUCCESS) { ++ syslog(LOG_CRIT, "pam_set_item(PAM_RHOST) failed: %d (%s)", ++ *pamret, pam_strerror(pamh, *pamret)); ++ return pamh; ++ } ++ ++#ifdef PAM_XDISPLAY ++ /* Let PAM modules use this to tag the session as a graphical one */ ++ *pamret = pam_set_item(pamh, PAM_XDISPLAY, display); ++ /* Note: PAM_XDISPLAY is only supported by modern versions of PAM */ ++ if (*pamret != PAM_BAD_ITEM && *pamret != PAM_SUCCESS) { ++ syslog(LOG_CRIT, "pam_set_item(PAM_XDISPLAY) failed: %d (%s)", ++ *pamret, pam_strerror(pamh, *pamret)); ++ return pamh; ++ } ++#endif ++ ++ /* Open session */ ++ *pamret = pam_open_session(pamh, PAM_SILENT); ++ if (*pamret != PAM_SUCCESS) { ++ syslog(LOG_CRIT, "pam_open_session failed: %d (%s)", ++ *pamret, pam_strerror(pamh, *pamret)); ++ return pamh; ++ } ++ ++ return pamh; ++} ++ ++static int ++stop_pam(pam_handle_t * pamh, int pamret) ++{ ++ /* Close session */ ++ if (pamret == PAM_SUCCESS) { ++ pamret = pam_close_session(pamh, PAM_SILENT); ++ if (pamret != PAM_SUCCESS) { ++ syslog(LOG_ERR, "pam_close_session failed: %d (%s)", ++ pamret, pam_strerror(pamh, pamret)); ++ } ++ } ++ ++ /* If PAM was OK and we are running on a SELinux system, new ++ processes images will be executed in the root context. */ ++ ++ /* Say goodbye */ ++ pamret = pam_end(pamh, pamret); ++ if (pamret != PAM_SUCCESS) { ++ /* avoid pam_strerror - we have no pamh. */ ++ syslog(LOG_ERR, "pam_end failed: %d", pamret); ++ return EX_OSERR; ++ } ++ return pamret; ++} ++ ++static char ** ++prepare_environ(pam_handle_t * pamh) ++{ ++ char **pam_env, **child_env, **entry; ++ int orig_count, pam_count; ++ ++ /* This function merges the normal environment with PAM's changes */ ++ ++ pam_env = pam_getenvlist(pamh); ++ if (pam_env == NULL) ++ return NULL; ++ ++ /* ++ * Worst case scenario is that PAM only adds variables, so allocate ++ * based on that assumption. ++ */ ++ orig_count = 0; ++ for (entry = environ; *entry != NULL; entry++) ++ orig_count++; ++ pam_count = 0; ++ for (entry = pam_env; *entry != NULL; entry++) ++ pam_count++; ++ ++ child_env = calloc(orig_count + pam_count + 1, sizeof(char *)); ++ if (child_env == NULL) ++ return NULL; ++ ++ memcpy(child_env, environ, sizeof(char *) * orig_count); ++ for (entry = child_env; *entry != NULL; entry++) { ++ *entry = strdup(*entry); ++ if (*entry == NULL) // FIXME: cleanup ++ return NULL; ++ } ++ ++ for (entry = pam_env; *entry != NULL; entry++) { ++ size_t varlen; ++ char **orig_entry; ++ ++ varlen = strcspn(*entry, "=") + 1; ++ ++ /* Check for overwrite */ ++ for (orig_entry = child_env; *orig_entry != NULL; orig_entry++) { ++ if (strncmp(*entry, *orig_entry, varlen) != 0) ++ continue; ++ ++ free(*orig_entry); ++ *orig_entry = *entry; ++ break; ++ } ++ ++ /* New variable? */ ++ if (*orig_entry == NULL) { ++ /* ++ * orig_entry will be pointing at the terminating entry, ++ * so we can just tack it on here. The new NULL was already ++ * prepared by calloc(). ++ */ ++ *orig_entry = *entry; ++ } ++ } ++ ++ return child_env; ++} ++ ++static void ++switch_user(const char *username, uid_t uid, gid_t gid) ++{ ++ // We must change group stuff first, because only root can do that. ++ if (setgid(gid) < 0) { ++ perror(": setgid"); ++ _exit(EX_OSERR); ++ } ++ ++ // Supplementary groups. ++ if (initgroups(username, gid) < 0) { ++ perror("initgroups"); ++ _exit(EX_OSERR); ++ } ++ ++ // Set euid, ruid and suid ++ if (setuid(uid) < 0) { ++ perror("setuid"); ++ _exit(EX_OSERR); ++ } ++} ++ ++static void ++redir_stdio(const char *homedir, const char *display) ++{ ++ int fd; ++ char hostname[HOST_NAME_MAX+1]; ++ char logfile[PATH_MAX]; ++ ++ fd = open("/dev/null", O_RDONLY); ++ if (fd == -1) { ++ perror("open"); ++ _exit(EX_OSERR); ++ } ++ if (dup2(fd, 0) == -1) { ++ perror("dup2"); ++ _exit(EX_OSERR); ++ } ++ close(fd); ++ ++ snprintf(logfile, sizeof(logfile), "%s/.vnc", homedir); ++ if (mkdir(logfile, 0755) == -1) { ++ if (errno != EEXIST) { ++ perror("mkdir"); ++ _exit(EX_OSERR); ++ } ++ } ++ ++ if (gethostname(hostname, sizeof(hostname)) == -1) { ++ perror("gethostname"); ++ _exit(EX_OSERR); ++ } ++ ++ snprintf(logfile, sizeof(logfile), "%s/.vnc/%s%s.log", ++ homedir, hostname, display); ++ fd = open(logfile, O_CREAT | O_WRONLY | O_TRUNC, 0644); ++ if (fd == -1) { ++ perror("open"); ++ _exit(EX_OSERR); ++ } ++ if ((dup2(fd, 1) == -1) || (dup2(fd, 2) == -1)) { ++ perror("dup2"); ++ _exit(EX_OSERR); ++ } ++ close(fd); ++} ++ ++static void ++close_fds(void) ++{ ++ DIR *dir; ++ struct dirent *entry; ++ ++ dir = opendir("/proc/self/fd"); ++ if (dir == NULL) { ++ perror("opendir"); ++ _exit(EX_OSERR); ++ } ++ ++ while ((entry = readdir(dir)) != NULL) { ++ int fd; ++ fd = atoi(entry->d_name); ++ if (fd < 3) ++ continue; ++ close(fd); ++ } ++ ++ closedir(dir); ++} ++ ++static pid_t ++run_script(const char *username, const char *display, char **envp) ++{ ++ struct passwd *pwent; ++ pid_t pid; ++ const char *child_argv[3]; ++ ++ pwent = getpwnam(username); ++ if (pwent == NULL) { ++ syslog(LOG_CRIT, "getpwnam: %s", strerror(errno)); ++ return -1; ++ } ++ ++ pid = fork(); ++ if (pid < 0) { ++ syslog(LOG_CRIT, "fork: %s", strerror(errno)); ++ return pid; ++ } ++ ++ /* two processes now */ ++ ++ if (pid > 0) ++ return pid; ++ ++ /* child */ ++ ++ switch_user(pwent->pw_name, pwent->pw_uid, pwent->pw_gid); ++ ++ close_fds(); ++ ++ redir_stdio(pwent->pw_dir, display); ++ ++ // execvpe() is not POSIX and is missing from older glibc ++ // First clear out everything ++ while ((environ != NULL) && (*environ != NULL)) { ++ char *var, *eq; ++ var = strdup(*environ); ++ eq = strchr(var, '='); ++ if (eq) ++ *eq = '\0'; ++ unsetenv(var); ++ free(var); ++ } ++ ++ // Then copy over the desired environment ++ for (; *envp != NULL; envp++) ++ putenv(*envp); ++ ++ // Set up some basic environment for the script ++ setenv("HOME", pwent->pw_dir, 1); ++ setenv("SHELL", pwent->pw_shell, 1); ++ setenv("LOGNAME", pwent->pw_name, 1); ++ setenv("USER", pwent->pw_name, 1); ++ setenv("USERNAME", pwent->pw_name, 1); ++ ++ child_argv[0] = CMAKE_INSTALL_FULL_LIBEXECDIR "/vncserver"; ++ child_argv[1] = display; ++ child_argv[2] = NULL; ++ ++ execvp(child_argv[0], (char*const*)child_argv); ++ ++ // execvp failed ++ perror("execvp"); ++ ++ _exit(EX_OSERR); ++} ++ ++int ++main(int argc, char **argv) ++{ ++ char pid_file[PATH_MAX]; ++ FILE *f; ++ ++ const char *username, *display; ++ ++ if ((argc != 3) || (argv[2][0] != ':')) { ++ fprintf(stderr, "Syntax:\n"); ++ fprintf(stderr, " %s \n", argv[0]); ++ return EX_USAGE; ++ } ++ ++ username = argv[1]; ++ display = argv[2]; ++ ++ if (geteuid() != 0) { ++ fprintf(stderr, "This program needs to be run as root!\n"); ++ return EX_USAGE; ++ } ++ ++ if (getpwnam(username) == NULL) { ++ if (errno == 0) ++ fprintf(stderr, "User \"%s\" does not exist\n", username); ++ else ++ fprintf(stderr, "Cannot look up user \"%s\": %s\n", ++ username, strerror(errno)); ++ return EX_OSERR; ++ } ++ ++ if (begin_daemon() == -1) ++ return EX_OSERR; ++ ++ openlog("vncsession", LOG_PID, LOG_AUTH); ++ ++ /* Indicate that this is a graphical user session. We need to do ++ this here before PAM as pam_systemd.so looks at these. */ ++ if ((putenv("XDG_SESSION_CLASS=user") < 0) || ++ (putenv("XDG_SESSION_TYPE=x11") < 0)) { ++ syslog(LOG_CRIT, "putenv: %s", strerror(errno)); ++ return EX_OSERR; ++ } ++ ++ /* Init PAM */ ++ int pamret; ++ pam_handle_t *pamh = run_pam(&pamret, username, display); ++ if (!pamh) { ++ return EX_OSERR; ++ } ++ if (pamret != PAM_SUCCESS) { ++ stop_pam(pamh, pamret); ++ return EX_OSERR; ++ } ++ ++ char **child_env; ++ child_env = prepare_environ(pamh); ++ if (child_env == NULL) { ++ syslog(LOG_CRIT, "Failure creating child process environment"); ++ stop_pam(pamh, pamret); ++ return EX_OSERR; ++ } ++ ++ setup_signals(); ++ ++ script = run_script(username, display, child_env); ++ if (script == -1) { ++ syslog(LOG_CRIT, "Failure starting vncserver script"); ++ stop_pam(pamh, pamret); ++ return EX_OSERR; ++ } ++ ++ snprintf(pid_file, sizeof(pid_file), ++ "/var/run/vncsession-%s.pid", display); ++ f = fopen(pid_file, "w"); ++ if (f == NULL) { ++ syslog(LOG_ERR, "Failure creating pid file \"%s\": %s", ++ pid_file, strerror(errno)); ++ } else { ++ fprintf(f, "%ld\n", (long)getpid()); ++ fclose(f); ++ } ++ ++ finish_daemon(); ++ ++ while (1) { ++ int status; ++ pid_t gotpid = waitpid(script, &status, 0); ++ if (gotpid < 0) { ++ if (errno != EINTR) { ++ syslog(LOG_CRIT, "waitpid: %s", strerror(errno)); ++ exit(EXIT_FAILURE); ++ } ++ continue; ++ } ++ if (WIFEXITED(status)) { ++ if (WEXITSTATUS(status) != 0) { ++ syslog(LOG_WARNING, ++ "vncsession: vncserver exited with status=%d", ++ WEXITSTATUS(status)); ++ } ++ break; ++ } ++ else if (WIFSIGNALED(status)) { ++ syslog(LOG_WARNING, ++ "vncsession: vncserver was terminated by signal %d", ++ WTERMSIG(status)); ++ break; ++ } ++ } ++ ++ unlink(pid_file); ++ ++ stop_pam(pamh, pamret); ++ ++ return 0; ++} +diff --git a/unix/vncserver/vncsession.man b/unix/vncserver/vncsession.man +new file mode 100644 +index 0000000..2138209 +--- /dev/null ++++ b/unix/vncserver/vncsession.man +@@ -0,0 +1,75 @@ ++.TH vncsession 8 "" "TigerVNC" "Virtual Network Computing" ++.SH NAME ++vncsession \- start a VNC server ++.SH SYNOPSIS ++.B vncsession ++.RI < username > ++.RI <: display# > ++.SH DESCRIPTION ++.B vncsession ++is used to start a VNC (Virtual Network Computing) desktop. ++.B vncsession ++performs all the necessary steps to create a new user session, run Xvnc with ++appropriate options and starts a window manager on the VNC desktop. ++ ++.B vncsession ++is rarely called directly and is normally started by the system service ++manager. ++ ++.SH FILES ++Several VNC-related files are found in the directory $HOME/.vnc: ++.TP ++/etc/tigervnc/vncserver-config-defaults ++The optional system-wide equivalent of $HOME/.vnc/config. If this file exists ++and defines options to be passed to Xvnc, they will be used as defaults for ++users. The user's $HOME/.vnc/config overrides settings configured in this file. ++The overall configuration file load order is: this file, $HOME/.vnc/config, ++and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist. ++.TP ++/etc/tigervnc/vncserver-config-mandatory ++The optional system-wide equivalent of $HOME/.vnc/config. If this file exists ++and defines options to be passed to Xvnc, they will override any of the same ++options defined in a user's $HOME/.vnc/config. This file offers a mechanism ++to establish some basic form of system-wide policy. WARNING! There is ++nothing stopping users from constructing their own vncsession-like script ++that calls Xvnc directly to bypass any options defined in ++/etc/tigervnc/vncserver-config-mandatory. The overall configuration file load ++order is: /etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then ++this file. None are required to exist. ++.TP ++$HOME/.vnc/config ++An optional server config file wherein options to be passed to Xvnc are listed ++to avoid hard-coding them to the physical invocation. List options in this file ++one per line. For those requiring an argument, simply separate the option from ++the argument with an equal sign, for example: "geometry=2000x1200" or ++"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed ++as a single word, for example: "localhost" or "alwaysshared". ++ ++The special option ++.B session ++can be used to control which session type will be started. This should match ++one of the files in \fI/usr/share/xsessions\fP. E.g. if there is a file called ++"gnome.desktop", then "session=gnome" would be set to use that session type. ++.TP ++$HOME/.vnc/passwd ++The VNC password file. ++.TP ++$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log ++The log file for Xvnc and the session. ++ ++.SH SEE ALSO ++.BR vncviewer (1), ++.BR vncpasswd (1), ++.BR vncconfig (1), ++.BR Xvnc (1) ++.br ++https://www.tigervnc.org ++ ++.SH AUTHOR ++Tristan Richardson, RealVNC Ltd., D. R. Commander and others. ++ ++VNC was originally developed by the RealVNC team while at Olivetti ++Research Ltd / AT&T Laboratories Cambridge. TightVNC additions were ++implemented by Constantin Kaplinsky. Many other people have since ++participated in development, testing and support. This manual is part ++of the TigerVNC software suite. +diff --git a/unix/x0vncserver/CMakeLists.txt b/unix/x0vncserver/CMakeLists.txt +index 8beade7..af82415 100644 +--- a/unix/x0vncserver/CMakeLists.txt ++++ b/unix/x0vncserver/CMakeLists.txt +@@ -52,5 +52,5 @@ endif() + + target_link_libraries(x0vncserver ${X11_LIBRARIES}) + +-install(TARGETS x0vncserver DESTINATION ${BIN_DIR}) +-install(FILES x0vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME x0vncserver.1) ++install(TARGETS x0vncserver DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) ++install(FILES x0vncserver.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME x0vncserver.1) +diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man +index 9c8a889..9559179 100644 +--- a/unix/xserver/hw/vnc/Xvnc.man ++++ b/unix/xserver/hw/vnc/Xvnc.man +@@ -18,9 +18,9 @@ that the VNC server display number will be the same as the X server display + number, which means you can use eg. snoopy:2 to refer to display 2 on machine + "snoopy" in both the X world and the VNC world. + +-The best way of starting \fBXvnc\fP is via the \fBvncserver\fP script. This +-sets up the environment appropriately and runs some X applications to get you +-going. See the manual page for \fBvncserver\fP(1) for more information. ++The best way of starting \fBXvnc\fP is via \fBvncsession\fP. This sets up the ++environment appropriately and starts a desktop environment. See the manual ++page for \fBvncsession\fP(8) for more information. + + .SH OPTIONS + .B Xvnc +@@ -383,8 +383,8 @@ created automatically the next time he connects. + .SH SEE ALSO + .BR vncconfig (1), + .BR vncpasswd (1), +-.BR vncserver (1), + .BR vncviewer (1), ++.BR vncsession (8), + .BR Xserver (1), + .BR inetd (1) + .br +diff --git a/vncviewer/CMakeLists.txt b/vncviewer/CMakeLists.txt +index 3c18646..7e25d45 100644 +--- a/vncviewer/CMakeLists.txt ++++ b/vncviewer/CMakeLists.txt +@@ -60,9 +60,9 @@ if(APPLE) + target_link_libraries(vncviewer "-framework IOKit") + endif() + +-install(TARGETS vncviewer DESTINATION ${BIN_DIR}) ++install(TARGETS vncviewer DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) + if(UNIX) +- install(FILES vncviewer.man DESTINATION ${MAN_DIR}/man1 RENAME vncviewer.1) ++ install(FILES vncviewer.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncviewer.1) + + configure_file(vncviewer.desktop.in.in vncviewer.desktop.in) + find_program(INTLTOOL_MERGE_EXECUTABLE intltool-merge) +@@ -91,10 +91,10 @@ if(UNIX) + ) + endif() + add_custom_target(desktop ALL DEPENDS vncviewer.desktop) +- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncviewer.desktop DESTINATION ${DATA_DIR}/applications) ++ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncviewer.desktop DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications) + + foreach(res 16 22 24 32 48) +- install(FILES ../media/icons/tigervnc_${res}.png DESTINATION ${DATA_DIR}/icons/hicolor/${res}x${res}/apps RENAME tigervnc.png) ++ install(FILES ../media/icons/tigervnc_${res}.png DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${res}x${res}/apps RENAME tigervnc.png) + endforeach() +- install(FILES ../media/icons/tigervnc.svg DESTINATION ${DATA_DIR}/icons/hicolor/scalable/apps) ++ install(FILES ../media/icons/tigervnc.svg DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps) + endif() +diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx +index 4a8370b..ae4cb6f 100644 +--- a/vncviewer/vncviewer.cxx ++++ b/vncviewer/vncviewer.cxx +@@ -227,7 +227,7 @@ static void init_fltk() + bool exists; + + sprintf(icon_path, "%s/icons/hicolor/%dx%d/apps/tigervnc.png", +- DATA_DIR, icon_sizes[i], icon_sizes[i]); ++ CMAKE_INSTALL_FULL_DATADIR, icon_sizes[i], icon_sizes[i]); + + #ifndef WIN32 + struct stat st; +@@ -505,7 +505,7 @@ int main(int argc, char** argv) + argv0 = argv[0]; + + setlocale(LC_ALL, ""); +- bindtextdomain(PACKAGE_NAME, LOCALE_DIR); ++ bindtextdomain(PACKAGE_NAME, CMAKE_INSTALL_FULL_LOCALEDIR); + textdomain(PACKAGE_NAME); + + rfb::SecurityClient::setDefaults(); +diff --git a/vncviewer/vncviewer.desktop.in.in b/vncviewer/vncviewer.desktop.in.in +index d775dde..9d658e4 100644 +--- a/vncviewer/vncviewer.desktop.in.in ++++ b/vncviewer/vncviewer.desktop.in.in +@@ -2,7 +2,7 @@ + Name=TigerVNC Viewer + GenericName=Remote Desktop Viewer + Comment=Connect to VNC server and display remote desktop +-Exec=@BIN_DIR@/vncviewer ++Exec=@CMAKE_INSTALL_FULL_BINDIR@/vncviewer + Icon=tigervnc + Terminal=false + Type=Application +diff --git a/vncviewer/vncviewer.man b/vncviewer/vncviewer.man +index f93e096..a8d8c77 100644 +--- a/vncviewer/vncviewer.man ++++ b/vncviewer/vncviewer.man +@@ -327,7 +327,7 @@ Default certificate revocation list. + .BR Xvnc (1), + .BR vncpasswd (1), + .BR vncconfig (1), +-.BR vncserver (1) ++.BR vncsession (8) + .br + https://www.tigervnc.org + diff --git a/SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch b/SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch deleted file mode 100644 index 1361d8b..0000000 --- a/SOURCES/tigervnc-vncserver-do-not-return-returncode-indicating-error.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/unix/vncserver b/unix/vncserver -index bb4f2feb..68be032d 100755 ---- a/unix/vncserver -+++ b/unix/vncserver -@@ -709,7 +709,7 @@ sub List - } - } - } -- exit 1; -+ exit; - } - - diff --git a/SOURCES/tigervnc-xstartup.patch b/SOURCES/tigervnc-xstartup.patch deleted file mode 100644 index 7098941..0000000 --- a/SOURCES/tigervnc-xstartup.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/unix/vncserver b/unix/vncserver -index bb4f2feb..b038dd3b 100755 ---- a/unix/vncserver -+++ b/unix/vncserver -@@ -58,27 +58,14 @@ $defaultXStartup - = ("#!/bin/sh\n\n". - "unset SESSION_MANAGER\n". - "unset DBUS_SESSION_BUS_ADDRESS\n". -- "OS=`uname -s`\n". -- "if [ \$OS = 'Linux' ]; then\n". -- " case \"\$WINDOWMANAGER\" in\n". -- " \*gnome\*)\n". -- " if [ -e /etc/SuSE-release ]; then\n". -- " PATH=\$PATH:/opt/gnome/bin\n". -- " export PATH\n". -- " fi\n". -- " ;;\n". -- " esac\n". -- "fi\n". -- "if [ -x /etc/X11/xinit/xinitrc ]; then\n". -- " exec /etc/X11/xinit/xinitrc\n". -- "fi\n". -- "if [ -f /etc/X11/xinit/xinitrc ]; then\n". -- " exec sh /etc/X11/xinit/xinitrc\n". -- "fi\n". -- "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n". -- "xsetroot -solid grey\n". -- "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n". -- "twm &\n"); -+ "/etc/X11/xinit/xinitrc\n". -+ "# Assume either Gnome will be started by default when installed\n". -+ "# We want to kill the session automatically in this case when user logs out. In case you modify\n". -+ "# /etc/X11/xinit/Xclients or ~/.Xclients yourself to achieve a different result, then you should\n". -+ "# be responsible to modify below code to avoid that your session will be automatically killed\n". -+ "if [ -e /usr/bin/gnome-session ]; then\n". -+ " vncserver -kill \$DISPLAY\n". -+ "fi\n"); - - $defaultConfig - = ("## Supported server options to pass to vncserver upon invocation can be listed\n". diff --git a/SOURCES/vncserver-system.service b/SOURCES/vncserver-system.service deleted file mode 100644 index 7b9cb2f..0000000 --- a/SOURCES/vncserver-system.service +++ /dev/null @@ -1,45 +0,0 @@ -# The vncserver service unit file -# -# Quick HowTo: -# 1. Copy this file to /etc/systemd/system/vncserver@.service -# 2. Replace with the actual user name and edit vncserver -# parameters in the wrapper script located in /usr/bin/vncserver_wrapper -# 3. Run `systemctl daemon-reload` -# 4. Run `systemctl enable vncserver@:.service` -# -# DO NOT RUN THIS SERVICE if your local area network is -# untrusted! For a secure way of using VNC, you should -# limit connections to the local host and then tunnel from -# the machine you want to view VNC on (host A) to the machine -# whose VNC output you want to view (host B) -# -# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB -# -# this will open a connection on port 590N of your hostA to hostB's port 590M -# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). -# See the ssh man page for details on port forwarding) -# -# You can then point a VNC client on hostA at vncdisplay N of localhost and with -# the help of ssh, you end up seeing what hostB makes available on port 590M -# -# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. -# -# Use "-localhost" to prevent remote VNC clients connecting except when -# doing so through a secure tunnel. See the "-via" option in the -# `man vncviewer' manual page. - - -[Unit] -Description=Remote desktop service (VNC) -After=syslog.target network.target - -[Service] -Type=simple - -# Clean any existing files in /tmp/.X11-unix environment -ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' -ExecStart=/usr/bin/vncserver_wrapper %i -ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' - -[Install] -WantedBy=multi-user.target diff --git a/SOURCES/vncserver-user.service b/SOURCES/vncserver-user.service deleted file mode 100644 index aed01e0..0000000 --- a/SOURCES/vncserver-user.service +++ /dev/null @@ -1,59 +0,0 @@ -# The vncserver service unit file -# -# Quick HowTo: As the User wanting to have this functionality -# -# 1. Copy this file to ~/.config/systemd/user/ (Optional, in case default settings are not suitable) -# -# $ mkdir -p ~/.config/systemd/user -# $ cp /usr/lib/systemd/user/vncserver@.service ~/.config/systemd/user/ -# -# 2. Reload user's systemd -# -# $ systemctl --user daemon-reload -# -# 3. Start the service immediately and enable it at boot -# -# $ systemctl --user enable vncserver@:.service --now -# -# 4. Enable lingering -# -# $ loginctl enable-linger -# -# DO NOT RUN THIS SERVICE if your local area network is -# untrusted! For a secure way of using VNC, you should -# limit connections to the local host and then tunnel from -# the machine you want to view VNC on (host A) to the machine -# whose VNC output you want to view (host B) -# -# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB -# -# this will open a connection on port 590N of your hostA to hostB's port 590M -# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). -# See the ssh man page for details on port forwarding) -# -# You can then point a VNC client on hostA at vncdisplay N of localhost and with -# the help of ssh, you end up seeing what hostB makes available on port 590M -# -# Use "-nolisten tcp" to prevent X connections to your VNC server via TCP. -# -# Use "-localhost" to prevent remote VNC clients connecting except when -# doing so through a secure tunnel. See the "-via" option in the -# `man vncviewer' manual page. - - -[Unit] -Description=Remote desktop service (VNC) -After=syslog.target network.target - -[Service] -Type=forking - -ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :' -ExecStart=/usr/bin/vncserver %i -ExecStop=/usr/bin/vncserver -kill %i - -Restart=on-success -RestartSec=15 - -[Install] -WantedBy=default.target diff --git a/SOURCES/vncserver.sysconfig b/SOURCES/vncserver.sysconfig deleted file mode 100644 index 4d0489b..0000000 --- a/SOURCES/vncserver.sysconfig +++ /dev/null @@ -1 +0,0 @@ -# THIS FILE HAS BEEN REPLACED BY /lib/systemd/system/vncserver@.service diff --git a/SOURCES/vncserver_wrapper b/SOURCES/vncserver_wrapper deleted file mode 100755 index 0c8f994..0000000 --- a/SOURCES/vncserver_wrapper +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -USER="$1" -INSTANCE="$2" - -die() { - echo "FATAL: ${@:-}" >&2 - exit 2 -} - -cleanup() { - [ -n "$VNCPID" ] || return - if kill -0 $VNCPID 2>/dev/null; then - kill $VNCPID - fi -} - -trap cleanup TERM INT HUP - -[ -n "$USER" -a -n "$INSTANCE" ] || die "Invalid usage!" - -/usr/sbin/runuser -l "$USER" -c "/usr/bin/vncserver ${INSTANCE}" -[ $? -eq 0 ] || die "'runuser -l $USER' failed!" - -# Wait up to 5 seconds for vncserver to be up -for tries in $(seq 1 50); do - [ -e "~$USER/.vnc/$(hostname)${INSTANCE}.pid" ] && break - sleep 0.1 -done - -eval HOME=~$USER - -VNCPID=$(cat "$HOME/.vnc/$(hostname)${INSTANCE}.pid" 2>/dev/null || true) -[ -n "$VNCPID" ] || die "'vncserver ${INSTANCE}' failed to start after 5 seconds!" - -echo "'vncserver ${INSTANCE}' has PID $VNCPID, waiting until it exits ..." - -while kill -0 $VNCPID 2>/dev/null; do - sleep 5 -done - -echo "PID $VNCPID exited, exiting ..." diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec index 7356149..d78ce25 100644 --- a/SPECS/tigervnc.spec +++ b/SPECS/tigervnc.spec @@ -1,6 +1,6 @@ Name: tigervnc -Version: 1.9.0 -Release: 15%{?dist} +Version: 1.10.1 +Release: 7%{?dist} Summary: A TigerVNC remote display system %global _hardened_build 1 @@ -9,41 +9,24 @@ License: GPLv2+ URL: http://www.tigervnc.com Source0: %{name}-%{version}.tar.gz -Source1: vncserver-system.service -Source2: vncserver-user.service -Source3: vncserver.sysconfig -Source4: 10-libvnc.conf -Source5: xvnc.service -Source6: xvnc.socket -Source7: vncserver_wrapper +Source1: xvnc.service +Source2: xvnc.socket +Source3: 10-libvnc.conf +Source4: HOWTO.md -Patch1: tigervnc-manpages.patch Patch2: tigervnc-getmaster.patch -Patch3: tigervnc-shebang.patch -Patch4: tigervnc-xstartup.patch Patch5: tigervnc-cursor.patch Patch6: tigervnc-1.3.1-CVE-2014-8240.patch -Patch7: tigervnc-1.3.1-do-not-die-when-port-is-already-taken.patch Patch8: tigervnc-let-user-know-about-not-using-view-only-password.patch Patch9: tigervnc-working-tls-on-fips-systems.patch Patch11: tigervnc-utilize-system-crypto-policies.patch Patch12: tigervnc-passwd-crash-with-malloc-checks.patch -Patch13: tigervnc-vncserver-do-not-return-returncode-indicating-error.patch - +Patch13: 0001-xserver-add-no-op-input-thread-init-function.patch Patch14: tigervnc-provide-correct-dimensions-for-xshm-setup.patch -Patch50: tigervnc-covscan.patch - -# Security fixes -Patch200: tigervnc-CVE-2019-15691.patch -Patch201: tigervnc-encapsulate-pixelbuffer-internal-details.patch -Patch202: tigervnc-CVE-2019-15692.patch -Patch203: tigervnc-add-write-protection-to-offsetpixelbuffer.patch -Patch204: tigervnc-CVE-2019-15693.patch -Patch205: tigervnc-pixelformat-sanity-checks.patch -Patch206: tigervnc-CVE-2019-15694.patch -Patch207: tigervnc-be-defensive-about-overflows-in-stream-objects.patch -Patch208: tigervnc-CVE-2019-15695.patch +# Upstream patches +Patch50: tigervnc-systemd-support.patch +Patch51: tigervnc-remove-trailing-spaces-in-user-name.patch # This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg Patch100: tigervnc-xserver120.patch @@ -55,12 +38,11 @@ BuildRequires: libX11-devel, automake, autoconf, libtool, gettext, gettext-auto BuildRequires: libXext-devel, xorg-x11-server-source, libXi-devel BuildRequires: xorg-x11-xtrans-devel, xorg-x11-util-macros, libXtst-devel BuildRequires: libxkbfile-devel, openssl-devel, libpciaccess-devel -BuildRequires: mesa-libGL-devel, libXinerama-devel +BuildRequires: mesa-libGL-devel, libXinerama-devel, xorg-x11-font-utils BuildRequires: freetype-devel, libXdmcp-devel, libxshmfence-devel -BuildRequires: desktop-file-utils, java-devel, jpackage-utils BuildRequires: libjpeg-turbo-devel, gnutls-devel, pam-devel BuildRequires: libdrm-devel, libXt-devel, pixman-devel -BuildRequires: systemd, cmake +BuildRequires: systemd, cmake, desktop-file-utils, selinux-policy-devel %if 0%{?fedora} > 24 || 0%{?rhel} >= 7 BuildRequires: libXfont2-devel %else @@ -70,9 +52,7 @@ BuildRequires: libXfont-devel # TigerVNC 1.4.x requires fltk 1.3.3 for keyboard handling support # See https://github.com/TigerVNC/tigervnc/issues/8, also bug #1208814 BuildRequires: fltk-devel >= 1.3.3 -%ifnarch s390 s390x BuildRequires: xorg-x11-server-devel -%endif Requires(post): coreutils Requires(postun):coreutils @@ -92,7 +72,8 @@ server. %package server Summary: A TigerVNC server Requires: perl-interpreter -Requires: tigervnc-server-minimal +Requires: tigervnc-server-minimal = %{version}-%{release} +Requires: tigervnc-selinux = %{version}-%{release} Requires: xorg-x11-xauth Requires: xorg-x11-xinit Requires(post): systemd @@ -113,7 +94,7 @@ Requires(post): chkconfig Requires(preun):chkconfig Requires: mesa-dri-drivers, xkeyboard-config, xorg-x11-xkb-utils -Requires: tigervnc-license +Requires: tigervnc-license, dbus-x11 %description server-minimal The VNC system allows you to access the same desktop from a wide @@ -121,7 +102,6 @@ variety of platforms. This package contains minimal installation of TigerVNC server, allowing others to access the desktop on your machine. -%ifnarch s390 s390x %package server-module Summary: TigerVNC module to Xorg Requires: xorg-x11-server-Xorg %(xserver-sdk-abi-requires ansic) %(xserver-sdk-abi-requires videodrv) @@ -130,16 +110,6 @@ Requires: tigervnc-license %description server-module This package contains libvnc.so module to X server, allowing others to access the desktop on your machine. -%endif - -%package server-applet -Summary: Java TigerVNC viewer applet for TigerVNC server -Requires: tigervnc-server, java, jpackage-utils -BuildArch: noarch - -%description server-applet -The Java TigerVNC viewer applet for web browsers. Install this package to allow -clients to use web browser when connect to the TigerVNC server. %package license Summary: License of TigerVNC suite @@ -155,6 +125,18 @@ BuildArch: noarch %description icons This package contains icons for TigerVNC viewer +%package selinux +Summary: SELinux module for TigerVNC +BuildArch: noarch +Requires(pre): libselinux-utils +Requires(post): selinux-policy >= %{_selinux_policy_version} +Requires(post): policycoreutils +Requires(post): libselinux-utils + +%description selinux +This package provides the SELinux policy module to ensure TigerVNC +runs properly under an environment with SELinux enabled. + %prep %setup -q @@ -167,19 +149,9 @@ done %patch101 -p1 -b .rpath popd -# Synchronise manpages and --help output (bug #980870). -%patch1 -p1 -b .manpages - # libvnc.so: don't use unexported GetMaster function (bug #744881 again). %patch2 -p1 -b .getmaster -# Don't use shebang in vncserver script. -%patch3 -p1 -b .shebang - -# Clearer xstartup file (bug #923655). -# Bug 1665876 - Tigervnc not starting on RHEL 7.6 server without -noxstartup option -%patch4 -p1 -b .xstartup - # Fixed viewer crash when cursor has not been set (bug #1051333). %patch5 -p1 -b .cursor @@ -187,9 +159,6 @@ popd # buffer overflow in screen size handling %patch6 -p1 -b .tigervnc-1.3.1-CVE-2014-8240 -# Bug 1322155 - Xorg socket conflict for VNC port 5901 -%patch7 -p1 -b .do-not-die-when-port-is-already-taken - # Bug 1447555 - view-only accepts enter, unclear whether default password is generated or not %patch8 -p1 -b .let-user-know-about-not-using-view-only-password @@ -201,22 +170,20 @@ popd %patch12 -p1 -b .passwd-crash-with-malloc-checks -%patch13 -p1 -b .vncserver-do-not-return-returncode-indicating-error +%patch13 -p1 -b .xserver-add-no-op-input-thread-init-function. -%patch50 -p1 -b .tigervnc-covscan +%patch14 -p1 -b .provide-correct-dimensions-for-xshm-setup -# Security fixes -%patch200 -p1 -b .CVE-2019-15691 -%patch201 -p1 -b .encapsulate-pixelbuffer-internal-details -%patch202 -p1 -b .CVE-2019-15692 -%patch203 -p1 -b .add-write-protection-to-offsetpixelbuffer -%patch204 -p1 -b .CVE-2019-15693 -%patch205 -p1 -b .pixelformat-sanity-checks -%patch206 -p1 -b .CVE-2019-15694 -%patch207 -p1 -b .be-defensive-about-overflows-in-stream-objects -%patch208 -p1 -b .CVE-2019-15695 +# HACK make sure we are able to successfuly apply a patch. This is because we will +# be creating a directory under name which already exists as a file and it also seems +# to be not possible to create a directory with a patch +pushd unix +rm vncserver +mkdir vncserver +popd -%patch14 -p1 -b .tigervnc-provide-correct-dimensions-for-xshm-setup +%patch50 -p1 -b .tigervnc-systemd-support +%patch51 -p1 -b .remove-trailing-spaces-in-user-name %build %ifarch sparcv9 sparc64 s390 s390x @@ -256,34 +223,27 @@ pushd media make popd -# Build Java applet -pushd java -%{cmake} . -JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8" make +# SELinux +pushd unix/vncserver/selinux +make popd + %install %make_install -rm -f %{buildroot}%{_docdir}/%{name}-%{version}/{README.rst,LICENCE.TXT} pushd unix/xserver/hw/vnc make install DESTDIR=%{buildroot} popd +pushd unix/vncserver/selinux +make install DESTDIR=%{buildroot} +popd + + # Install systemd unit file -mkdir -p %{buildroot}%{_unitdir} -mkdir -p %{buildroot}%{_userunitdir} -install -m644 %{SOURCE1} %{buildroot}%{_unitdir}/vncserver@.service -install -m644 %{SOURCE2} %{buildroot}%{_userunitdir}/vncserver@.service -install -m644 %{SOURCE5} %{buildroot}%{_unitdir}/xvnc@.service -install -m644 %{SOURCE6} %{buildroot}%{_unitdir}/xvnc.socket -rm -rf %{buildroot}%{_initrddir} - -# Install vncserver wrapper script -install -m744 %{SOURCE7} %{buildroot}%{_bindir}/vncserver_wrapper - -mkdir -p %{buildroot}%{_sysconfdir}/sysconfig -install -m644 %{SOURCE3} %{buildroot}%{_sysconfdir}/sysconfig/vncservers +install -m644 %{SOURCE1} %{buildroot}%{_unitdir}/xvnc@.service +install -m644 %{SOURCE2} %{buildroot}%{_unitdir}/xvnc.socket # Install desktop stuff mkdir -p %{buildroot}%{_datadir}/icons/hicolor/{16x16,24x24,48x48}/apps @@ -294,41 +254,54 @@ install -m644 tigervnc_$s.png %{buildroot}%{_datadir}/icons/hicolor/${s}x$s/apps done popd - -# Install Java applet -pushd java -mkdir -p %{buildroot}%{_datadir}/vnc/classes -install -m755 VncViewer.jar %{buildroot}%{_datadir}/vnc/classes -install -m644 com/tigervnc/vncviewer/index.vnc %{buildroot}%{_datadir}/vnc/classes -popd +# Install a replacement for /usr/bin/vncserver which will tell the user to read the +# HOWTO.md file +cat < %{buildroot}/%{_bindir}/vncserver +#!/bin/bash +echo "vncserver has been replaced by a systemd unit." +echo "Please read /usr/share/doc/tigervnc/HOWTO.md for more information." +EOF +chmod +x %{buildroot}/%{_bindir}/vncserver %find_lang %{name} %{name}.lang # remove unwanted files rm -f %{buildroot}%{_libdir}/xorg/modules/extensions/libvnc.la -%ifarch s390 s390x -rm -f %{buildroot}%{_libdir}/xorg/modules/extensions/libvnc.so -%else mkdir -p %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/ -install -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf -%endif +install -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf + +install -m 644 %{SOURCE4} %{buildroot}/%{_docdir}/tigervnc/HOWTO.md %post server -%systemd_post vncserver.service %systemd_post xvnc.service %systemd_post xvnc.socket %preun server -%systemd_preun vncserver.service %systemd_preun xvnc.service %systemd_preun xvnc.socket %postun server -%systemd_postun vncserver.service %systemd_postun xvnc.service %systemd_postun xvnc.socket +%pre selinux +%selinux_relabel_pre + +%post selinux +%selinux_modules_install %{_datadir}/selinux/packages/vncsession.pp +%selinux_relabel_post + +%posttrans selinux +%selinux_relabel_post + +%postun selinux +%selinux_modules_uninstall vncsession +if [ $1 -eq 0 ]; then + %selinux_relabel_post +fi + + %files -f %{name}.lang %doc README.rst %{_bindir}/vncviewer @@ -336,16 +309,22 @@ install -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/10-libvnc.c %{_mandir}/man1/vncviewer.1* %files server -%config(noreplace) %{_sysconfdir}/sysconfig/vncservers -%{_userunitdir}/vncserver@.service +%config(noreplace) %{_sysconfdir}/pam.d/tigervnc +%config(noreplace) %{_sysconfdir}/tigervnc/vncserver-config-defaults +%config(noreplace) %{_sysconfdir}/tigervnc/vncserver-config-mandatory +%config(noreplace) %{_sysconfdir}/tigervnc/vncserver.users %{_unitdir}/vncserver@.service %{_unitdir}/xvnc@.service %{_unitdir}/xvnc.socket %{_bindir}/x0vncserver %{_bindir}/vncserver -%{_bindir}/vncserver_wrapper -%{_mandir}/man1/vncserver.1* +%{_sbindir}/vncsession +%{_libexecdir}/vncserver +%{_libexecdir}/vncsession-start %{_mandir}/man1/x0vncserver.1* +%{_mandir}/man8/vncserver.8* +%{_mandir}/man8/vncsession.8* +%{_docdir}/tigervnc/HOWTO.md %files server-minimal %{_bindir}/vncconfig @@ -355,62 +334,64 @@ install -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/X11/xorg.conf.d/10-libvnc.c %{_mandir}/man1/vncpasswd.1* %{_mandir}/man1/vncconfig.1* -%ifnarch s390 s390x %files server-module %{_libdir}/xorg/modules/extensions/libvnc.so %config %{_sysconfdir}/X11/xorg.conf.d/10-libvnc.conf -%endif - -%files server-applet -%doc java/com/tigervnc/vncviewer/README -%{_datadir}/vnc/classes/* %files license -%license LICENCE.TXT +%{_docdir}/tigervnc/LICENCE.TXT %files icons %{_datadir}/icons/hicolor/*/apps/* +%files selinux +%{_datadir}/selinux/packages/vncsession.pp + + %changelog -* Thu Apr 22 2020 Jan Grulich - 1.9.0-15 -- Bump build version - Resolves: bz#1819877 - Resolves: bz#1819879 - Resolves: bz#1819882 - Resolves: bz#1819886 - Resolves: bz#1819884 +* Wed Jul 08 2020 Jan Grulich - 1.10.1-7 +- Enable server module on s390x + Resolves: bz#1854925 -* Thu Apr 09 2020 Jan Grulich - 1.9.0-14 -- Bump build version - Resolves: bz#1819877 - Resolves: bz#1819879 - Resolves: bz#1819882 - Resolves: bz#1819886 - Resolves: bz#1819884 +* Fri Jul 03 2020 Jan Grulich - 1.10.1-6 +- Remove trailing spaces in user name + Resolves: bz#1852432 -* Wed Apr 08 2020 Jan Grulich - 1.9.0-13 -- Fix stack buffer overflow in CMsgReader::readSetCursor - Resolves: bz#1819877 +* Thu Jun 25 2020 Jan Grulich - 1.10.1-5 +- Install the HOWTO file to correct location +- Add /usr/bin/vncserver file informing users to read the HOWTO.md file + Resolves: bz#1790443 -- Fix heap buffer overflow in DecodeManager::decodeRect - Resolves: bz#1819879 +* Mon Jun 15 2020 Jan Grulich - 1.10.1-4 +- Improve SELinux policy + Resolves: bz#1790443 -- Fix heap buffer overflow in TightDecoder::FilterGradient - Resolves: bz#1819882 +* Mon Jun 15 2020 Jan Grulich - 1.10.1-3 +- Add a HOWTO.md file with instructions how to start VNC server + Resolves: bz#1790443 -- Fix heap-based buffer overflow triggered from CopyRectDecoder - Resolves: bz#1819886 +* Tue May 26 2020 Jan Grulich - 1.10.1-2 +- Make the systemd service run also for root user + Resolves: bz#1790443 -- Fix stack use-after-return due to incorrect usage of stack memory in ZRLEDecoder - Resolves: bz#1819884 +* Mon Apr 27 2020 Jan Grulich - 1.10.1-1 +- Update to 1.10.1 + Resolves: bz#1806992 -* Tue Jan 28 2020 Jan Grulich - 1.9.0-12 -- Fix installation of 10-libvnc.conf file - Resolves: bz#1795168 +- Add proper systemd support + Resolves: bz#1790443 -* Mon Jan 27 2020 Jan Grulich - 1.9.0-11 +* Tue Jan 28 2020 Jan Grulich - 1.9.0-13 +- Bump build because of z-stream + Resolves: bz#1671714 + +* Wed Dec 11 2019 Jan Grulich - 1.9.0-12 +- Fix installation of systemd files + Resolves: bz#1671714 + +* Wed Nov 20 2019 Jan Grulich - 1.9.0-11 - Use wrapper script to workaround systemd issues - Resolves: bz#1795168 + Resolves: bz#1671714 * Fri Jul 12 2019 Jan Grulich - 1.9.0-10 - Do not return returncode indicating error when running "vncserver -list"