import tigervnc-1.9.0-14.el8_1

This commit is contained in:
CentOS Sources 2020-04-16 16:10:31 -04:00 committed by Andrew Lukoshko
commit 8215c2e14f
34 changed files with 4698 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/tigervnc-1.9.0.tar.gz

1
.tigervnc.metadata Normal file
View File

@ -0,0 +1 @@
c56656c596fb863bb2c4b67fb62b4165011d181f SOURCES/tigervnc-1.9.0.tar.gz

View File

@ -0,0 +1,28 @@
From 2489f2f38eb32d9dd03718a36cbdbdf13d2f8b9b Mon Sep 17 00:00:00 2001
From: Adam Jackson <ajax@redhat.com>
Date: Thu, 12 Nov 2015 11:10:11 -0500
Subject: [PATCH] rpath hack
Normally, rpath is undesirable. But for the X server we _know_ we need
Mesa's libGL, which will always be in %{_libdir}, and not any third-party
libGL that may be configured using ld.so.conf.
---
configure.ac | 1 +
1 files changed, 1 insertions(+), 0 deletion(-)
diff --git a/configure.ac b/configure.ac
index fa15a2d..a5af1e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1357,6 +1357,7 @@ else
fi
AM_CONDITIONAL(GLX, test "x$GLX" = xyes)
+GLX_SYS_LIBS="$GLX_SYS_LIBS -Wl,-rpath=\$(libdir)"
AC_SUBST([GLX_DEFINES])
AC_SUBST([GLX_SYS_LIBS])
--
2.5.0

19
SOURCES/10-libvnc.conf Normal file
View File

@ -0,0 +1,19 @@
# This file contains configuration of libvnc.so module
#
# To get libvnc.so module working, do this:
# 1. run "vncpasswd" from tigervnc-server package as root user
# 2. uncomment configuration lines below
#
# Please note you can specify any option which Xvnc accepts.
# Refer to `Xvnc -help` output for detailed list of options.
#Section "Module"
# Load "vnc"
#EndSection
#Section "Screen"
# Identifier "Screen0"
# DefaultDepth 16
# Option "SecurityTypes" "VncAuth"
# Option "PasswordFile" "/root/.vnc/passwd"
#EndSection

View File

@ -0,0 +1,74 @@
diff --git a/unix/x0vncserver/Image.cxx b/unix/x0vncserver/Image.cxx
index f998c6a..fb9dbd4 100644
--- a/unix/x0vncserver/Image.cxx
+++ b/unix/x0vncserver/Image.cxx
@@ -80,6 +80,14 @@ void Image::Init(int width, int height)
xim = XCreateImage(dpy, vis, DefaultDepth(dpy, DefaultScreen(dpy)),
ZPixmap, 0, 0, width, height, BitmapPad(dpy), 0);
+ if (xim->bytes_per_line <= 0 ||
+ xim->height <= 0 ||
+ xim->height >= INT_MAX / xim->bytes_per_line) {
+ vlog.error("Invalid display size");
+ XDestroyImage(xim);
+ exit(1);
+ }
+
xim->data = (char *)malloc(xim->bytes_per_line * xim->height);
if (xim->data == NULL) {
vlog.error("malloc() failed");
@@ -256,6 +264,17 @@ void ShmImage::Init(int width, int height, const XVisualInfo *vinfo)
return;
}
+ if (xim->bytes_per_line <= 0 ||
+ xim->height <= 0 ||
+ xim->height >= INT_MAX / xim->bytes_per_line) {
+ vlog.error("Invalid display size");
+ XDestroyImage(xim);
+ xim = NULL;
+ delete shminfo;
+ shminfo = NULL;
+ return;
+ }
+
shminfo->shmid = shmget(IPC_PRIVATE,
xim->bytes_per_line * xim->height,
IPC_CREAT|0777);
diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx
index a2b506d..9266d9f 100644
--- a/vncviewer/PlatformPixelBuffer.cxx
+++ b/vncviewer/PlatformPixelBuffer.cxx
@@ -49,6 +49,15 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) :
if (!xim)
throw rdr::Exception("XCreateImage");
+ if (xim->bytes_per_line <= 0 ||
+ xim->height <= 0 ||
+ xim->height >= INT_MAX / xim->bytes_per_line) {
+ if (xim)
+ XDestroyImage(xim);
+ xim = NULL;
+ throw rdr::Exception("Invalid display size");
+ }
+
xim->data = (char*)malloc(xim->bytes_per_line * xim->height);
if (!xim->data)
throw rdr::Exception("malloc");
@@ -152,6 +161,16 @@ bool PlatformPixelBuffer::setupShm()
if (!xim)
goto free_shminfo;
+ if (xim->bytes_per_line <= 0 ||
+ xim->height <= 0 ||
+ xim->height >= INT_MAX / xim->bytes_per_line) {
+ XDestroyImage(xim);
+ xim = NULL;
+ delete shminfo;
+ shminfo = NULL;
+ throw rdr::Exception("Invalid display size");
+ }
+
shminfo->shmid = shmget(IPC_PRIVATE,
xim->bytes_per_line * xim->height,
IPC_CREAT|0600);

View File

@ -0,0 +1,14 @@
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();

View File

@ -0,0 +1,116 @@
From d61a767d6842b530ffb532ddd5a3d233119aad40 Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
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

View File

@ -0,0 +1,71 @@
From 996356b6c65ca165ee1ea46a571c32a1dc3c3821 Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
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_;

View File

@ -0,0 +1,75 @@
From b4ada8d0c6dac98c8b91fc64d112569a8ae5fb95 Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
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) {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
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;
}

View File

@ -0,0 +1,51 @@
From 9f615301aba1cc54a749950bf9462c5a85217bc4 Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
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 <rfb/SMsgWriter.h>
#include <rfb/UpdateTracker.h>
#include <rfb/LogWriter.h>
+#include <rfb/Exception.h>
#include <rfb/RawEncoder.h>
#include <rfb/RREEncoder.h>
@@ -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;

View File

@ -0,0 +1,355 @@
From 75e6e0653a48baf474fd45d78b1da53e2f324642 Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
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 <rdr/Exception.h>
#include <rdr/OutStream.h>
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;
}

View File

@ -0,0 +1,312 @@
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 <list>
#include <stdio.h>
#include <stdlib.h>
+#include <vector>
#include <rfb/util.h>
std::list<TXWindow*> 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<bool> 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<bool> shared;
+ std::vector<bool> 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;

View File

@ -0,0 +1,12 @@
diff -up tigervnc-1.3.0/vncviewer/Viewport.cxx.cursor tigervnc-1.3.0/vncviewer/Viewport.cxx
--- tigervnc-1.3.0/vncviewer/Viewport.cxx.cursor 2013-12-17 13:28:23.170400013 +0000
+++ tigervnc-1.3.0/vncviewer/Viewport.cxx 2013-12-17 13:29:46.095784064 +0000
@@ -248,7 +248,7 @@ void Viewport::setCursor(int width, int height, const Point& hotspot,
}
}
- if (Fl::belowmouse() == this)
+ if (Fl::belowmouse() == this && cursor)
window()->cursor(cursor, cursorHotspot.x, cursorHotspot.y);
}

View File

@ -0,0 +1,526 @@
From 53f913a76196c7357d4858bfbf2c33caa9181bae Mon Sep 17 00:00:00 2001
From: Pierre Ossman <ossman@cendio.se>
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<rfb::Rect> 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<network::SocketListener*> listeners;
std::list<network::SocketListener*> 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;

View File

@ -0,0 +1,88 @@
diff --git a/unix/xserver/hw/vnc/InputXKB.c b/unix/xserver/hw/vnc/InputXKB.c
index a9bd11d..7b54b43 100644
--- a/unix/xserver/hw/vnc/InputXKB.c
+++ b/unix/xserver/hw/vnc/InputXKB.c
@@ -214,10 +214,7 @@ void vncPrepareInputDevices(void)
unsigned vncGetKeyboardState(void)
{
- DeviceIntPtr master;
-
- master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT);
- return XkbStateFieldFromRec(&master->key->xkbInfo->state);
+ return XkbStateFieldFromRec(&vncKeyboardDev->master->key->xkbInfo->state);
}
unsigned vncGetLevelThreeMask(void)
@@ -238,7 +235,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)
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)
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)
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)
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)
*new_state = state;
- 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)
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)
KeySym *syms;
KeySym upper, lower;
- master = GetMaster(vncKeyboardDev, KEYBOARD_OR_FLOAT);
+ master = vncKeyboardDev->master;
xkb = master->key->xkbInfo->desc;
for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) {
if (XkbKeyNumGroups(xkb, key) == 0)

View File

@ -0,0 +1,13 @@
diff --git a/unix/vncpasswd/vncpasswd.cxx b/unix/vncpasswd/vncpasswd.cxx
index 16c925ee..6398121e 100644
--- a/unix/vncpasswd/vncpasswd.cxx
+++ b/unix/vncpasswd/vncpasswd.cxx
@@ -150,6 +150,8 @@ int main(int argc, char** argv)
char yesno[3];
if (fgets(yesno, 3, stdin) != NULL && (yesno[0] == 'y' || yesno[0] == 'Y')) {
obfuscatedReadOnly = readpassword();
+ } else {
+ fprintf(stderr, "A view-only password is not used\n");
}
FILE* fp = fopen(fname,"w");

View File

@ -0,0 +1,28 @@
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 <width>x<height>]\n".
" [-pixelformat rgbNNN|bgrNNN]\n".
" [-fp <font-path>]\n".
+ " [-cc <visual>]\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 -<param> or off with -<param>=0\n"
"Parameters which take a value can be specified as "

View File

@ -0,0 +1,13 @@
diff --git a/common/rfb/util.h b/common/rfb/util.h
index b678b89..9e59bd3 100644
--- a/common/rfb/util.h
+++ b/common/rfb/util.h
@@ -50,7 +50,7 @@ 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() {
delete [] buf;

View File

@ -0,0 +1,32 @@
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;

View File

@ -0,0 +1,9 @@
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.

View File

@ -0,0 +1,13 @@
diff --git a/common/rfb/Security.cxx b/common/rfb/Security.cxx
index e623ab5..4987b29 100644
--- a/common/rfb/Security.cxx
+++ b/common/rfb/Security.cxx
@@ -52,7 +52,7 @@ static LogWriter vlog("Security");
#ifdef HAVE_GNUTLS
StringParameter Security::GnuTLSPriority("GnuTLSPriority",
"GnuTLS priority string that controls the TLS sessions handshake algorithms",
- "NORMAL");
+ "@SYSTEM");
#endif
Security::Security()

View File

@ -0,0 +1,13 @@
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;
}

View File

@ -0,0 +1,13 @@
diff --git a/common/rfb/SSecurityTLS.cxx b/common/rfb/SSecurityTLS.cxx
index b946022..2daefa2 100644
--- a/common/rfb/SSecurityTLS.cxx
+++ b/common/rfb/SSecurityTLS.cxx
@@ -186,7 +186,7 @@ void SSecurityTLS::setParams(gnutls_session_t session)
if (gnutls_dh_params_init(&dh_params) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_dh_params_init failed");
- if (gnutls_dh_params_generate2(dh_params, DH_BITS) != GNUTLS_E_SUCCESS)
+ if (gnutls_dh_params_generate2(dh_params, gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM)) != GNUTLS_E_SUCCESS)
throw AuthFailureException("gnutls_dh_params_generate2 failed");
if (anon) {

View File

@ -0,0 +1,91 @@
diff -up xserver/configure.ac.xserver116-rebased xserver/configure.ac
--- xserver/configure.ac.xserver116-rebased 2016-09-29 13:14:45.595441590 +0200
+++ xserver/configure.ac 2016-09-29 13:14:45.631442006 +0200
@@ -74,6 +74,7 @@ dnl forcing an entire recompile.x
AC_CONFIG_HEADERS(include/version-config.h)
AM_PROG_AS
+AC_PROG_CXX
AC_PROG_LN_S
LT_PREREQ([2.2])
LT_INIT([disable-static win32-dll])
@@ -1863,6 +1864,10 @@ if test "x$XVFB" = xyes; then
AC_SUBST([XVFB_SYS_LIBS])
fi
+dnl Xvnc DDX
+AC_SUBST([XVNC_CPPFLAGS], ["-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"])
+AC_SUBST([XVNC_LIBS], ["$FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $DRI3_LIB $PRESENT_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB"])
+AC_SUBST([XVNC_SYS_LIBS], ["$GLX_SYS_LIBS"])
dnl Xnest DDX
@@ -1898,6 +1903,8 @@ if test "x$XORG" = xauto; then
fi
AC_MSG_RESULT([$XORG])
+AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+
if test "x$XORG" = xyes; then
XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
@@ -2116,7 +2123,6 @@ if test "x$XORG" = xyes; then
AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
- AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
@@ -2691,6 +2697,7 @@ hw/dmx/Makefile
hw/dmx/man/Makefile
hw/vfb/Makefile
hw/vfb/man/Makefile
+hw/vnc/Makefile
hw/xnest/Makefile
hw/xnest/man/Makefile
hw/xwin/Makefile
diff -up xserver/hw/Makefile.am.xserver116-rebased xserver/hw/Makefile.am
--- xserver/hw/Makefile.am.xserver116-rebased 2016-09-29 13:14:45.601441659 +0200
+++ xserver/hw/Makefile.am 2016-09-29 13:14:45.631442006 +0200
@@ -38,7 +38,8 @@ SUBDIRS = \
$(DMX_SUBDIRS) \
$(KDRIVE_SUBDIRS) \
$(XQUARTZ_SUBDIRS) \
- $(XWAYLAND_SUBDIRS)
+ $(XWAYLAND_SUBDIRS) \
+ vnc
DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland
diff --git xserver/mi/miinitext.c xserver/mi/miinitext.c
index 5596e21..003fc3c 100644
--- xserver/mi/miinitext.c
+++ xserver/mi/miinitext.c
@@ -107,8 +107,15 @@ SOFTWARE.
#include "os.h"
#include "globals.h"
+#ifdef TIGERVNC
+extern void vncExtensionInit(INITARGS);
+#endif
+
/* List of built-in (statically linked) extensions */
static const ExtensionModule staticExtensions[] = {
+#ifdef TIGERVNC
+ {vncExtensionInit, "VNC-EXTENSION", NULL},
+#endif
{GEExtensionInit, "Generic Event Extension", &noGEExtension},
{ShapeExtensionInit, "SHAPE", NULL},
#ifdef MITSHM
--- xserver/include/os.h~ 2016-10-03 09:07:29.000000000 +0200
+++ xserver/include/os.h 2016-10-03 14:13:00.013654506 +0200
@@ -621,7 +621,7 @@
extern _X_EXPORT void
LogClose(enum ExitCode error);
extern _X_EXPORT Bool
-LogSetParameter(LogParameter param, int value);
+LogSetParameter(enum _LogParameter param, int value);
extern _X_EXPORT void
LogVWrite(int verb, const char *f, va_list args)
_X_ATTRIBUTE_PRINTF(2, 0);

View File

@ -0,0 +1,40 @@
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".

View File

@ -0,0 +1,45 @@
# The vncserver service unit file
#
# Quick HowTo:
# 1. Copy this file to /etc/systemd/system/vncserver@.service
# 2. Replace <USER> 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@:<display>.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 <USER> %i
ExecStop=/bin/sh -c '/usr/bin/vncserver -kill %i > /dev/null 2>&1 || :'
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,59 @@
# 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@:<display>.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

View File

@ -0,0 +1 @@
# THIS FILE HAS BEEN REPLACED BY /lib/systemd/system/vncserver@.service

42
SOURCES/vncserver_wrapper Executable file
View File

@ -0,0 +1,42 @@
#!/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 ..."

38
SOURCES/xvnc.service Normal file
View File

@ -0,0 +1,38 @@
# The vncserver service unit file
#
# Quick HowTo:
# 1. Copy this file to /etc/systemd/system/xvnc@.service
# 2. Copy xvnc.socket to /etc/systemd/system/xvnc.socket
# 3. Run `systemctl daemon-reload`
# 4. Run `systemctl enable xvnc.socket`
#
# 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=XVNC Per-Connection Daemon
[Service]
ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 24 -once -SecurityTypes=None
User=nobody
StandardInput=socket
StandardError=syslog

9
SOURCES/xvnc.socket Normal file
View File

@ -0,0 +1,9 @@
[Unit]
Description=XVNC Server
[Socket]
ListenStream=5900
Accept=yes
[Install]
WantedBy=sockets.target

1060
SPECS/tigervnc.spec Normal file

File diff suppressed because it is too large Load Diff