summaryrefslogtreecommitdiffstats
path: root/libvncclient
diff options
context:
space:
mode:
Diffstat (limited to 'libvncclient')
-rw-r--r--libvncclient/corre.c2
-rw-r--r--libvncclient/rfbproto.c109
-rw-r--r--libvncclient/sasl.c3
-rw-r--r--libvncclient/sockets.c3
-rw-r--r--libvncclient/tight.c2
-rw-r--r--libvncclient/tls.h2
-rw-r--r--libvncclient/tls_gnutls.c2
-rw-r--r--libvncclient/tls_none.c2
-rw-r--r--libvncclient/tls_openssl.c2
-rw-r--r--libvncclient/ultra.c4
-rw-r--r--libvncclient/vncviewer.c6
11 files changed, 101 insertions, 36 deletions
diff --git a/libvncclient/corre.c b/libvncclient/corre.c
index 66e3b08..cbc986a 100644
--- a/libvncclient/corre.c
+++ b/libvncclient/corre.c
@@ -48,7 +48,7 @@ HandleCoRREBPP (rfbClient* client, int rx, int ry, int rw, int rh)
client->GotFillRect(client, rx, ry, rw, rh, pix);
- if (!ReadFromRFBServer(client, client->buffer, hdr.nSubrects * (4 + (BPP / 8))))
+ if (hdr.nSubrects > RFB_BUFFER_SIZE / (4 + (BPP / 8)) || !ReadFromRFBServer(client, client->buffer, hdr.nSubrects * (4 + (BPP / 8))))
return FALSE;
ptr = (uint8_t *)client->buffer;
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c
index e5373bc..2f887c3 100644
--- a/libvncclient/rfbproto.c
+++ b/libvncclient/rfbproto.c
@@ -61,7 +61,11 @@
#endif
#include "sasl.h"
+#ifdef LIBVNCSERVER_HAVE_LZO
+#include <lzo/lzo1x.h>
+#else
#include "minilzo.h"
+#endif
#include "tls.h"
#ifdef _MSC_VER
@@ -363,6 +367,7 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep
rfbProtocolVersionMsg pv;
int major,minor;
char tmphost[250];
+ int tmphostlen;
#ifdef LIBVNCSERVER_IPv6
client->sock = ConnectClientToTcpAddr6(repeaterHost, repeaterPort);
@@ -398,8 +403,11 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep
rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor);
- snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort);
- if (!WriteToRFBServer(client, tmphost, sizeof(tmphost)))
+ tmphostlen = snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort);
+ if(tmphostlen < 0 || tmphostlen >= (int)sizeof(tmphost))
+ return FALSE; /* snprintf error or output truncated */
+
+ if (!WriteToRFBServer(client, tmphost, tmphostlen + 1))
return FALSE;
return TRUE;
@@ -408,11 +416,29 @@ rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int rep
extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
+static void
+ReadReason(rfbClient* client)
+{
+ uint32_t reasonLen;
+ char *reason;
+
+ if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
+ reasonLen = rfbClientSwap32IfLE(reasonLen);
+ if(reasonLen > 1<<20) {
+ rfbClientLog("VNC connection failed, but sent reason length of %u exceeds limit of 1MB",(unsigned int)reasonLen);
+ return;
+ }
+ reason = malloc(reasonLen+1);
+ if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
+ reason[reasonLen]=0;
+ rfbClientLog("VNC connection failed: %s\n",reason);
+ free(reason);
+}
+
rfbBool
rfbHandleAuthResult(rfbClient* client)
{
- uint32_t authResult=0, reasonLen=0;
- char *reason=NULL;
+ uint32_t authResult=0;
if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
@@ -427,13 +453,7 @@ rfbHandleAuthResult(rfbClient* client)
if (client->major==3 && client->minor>7)
{
/* we have an error following */
- if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
- reasonLen = rfbClientSwap32IfLE(reasonLen);
- reason = malloc(reasonLen+1);
- if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
- reason[reasonLen]=0;
- rfbClientLog("VNC connection failed: %s\n",reason);
- free(reason);
+ ReadReason(client);
return FALSE;
}
rfbClientLog("VNC authentication failed\n");
@@ -448,21 +468,6 @@ rfbHandleAuthResult(rfbClient* client)
return FALSE;
}
-static void
-ReadReason(rfbClient* client)
-{
- uint32_t reasonLen;
- char *reason;
-
- /* we have an error following */
- if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
- reasonLen = rfbClientSwap32IfLE(reasonLen);
- reason = malloc(reasonLen+1);
- if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
- reason[reasonLen]=0;
- rfbClientLog("VNC connection failed: %s\n",reason);
- free(reason);
-}
static rfbBool
ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
@@ -470,9 +475,11 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
uint8_t count=0;
uint8_t loop=0;
uint8_t flag=0;
+ rfbBool extAuthHandler;
uint8_t tAuth[256];
char buf1[500],buf2[10];
uint32_t authScheme;
+ rfbClientProtocolExtension* e;
if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
@@ -491,7 +498,18 @@ ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
if (flag) continue;
+ extAuthHandler=FALSE;
+ for (e = rfbClientExtensions; e; e = e->next) {
+ if (!e->handleAuthentication) continue;
+ uint32_t const* secType;
+ for (secType = e->securityTypes; secType && *secType; secType++) {
+ if (tAuth[loop]==*secType) {
+ extAuthHandler=TRUE;
+ }
+ }
+ }
if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth ||
+ extAuthHandler ||
#if defined(LIBVNCSERVER_HAVE_GNUTLS) || defined(LIBVNCSERVER_HAVE_LIBSSL)
tAuth[loop]==rfbVeNCrypt ||
#endif
@@ -1172,6 +1190,22 @@ InitialiseRFBConnection(rfbClient* client)
break;
default:
+ {
+ rfbBool authHandled=FALSE;
+ rfbClientProtocolExtension* e;
+ for (e = rfbClientExtensions; e; e = e->next) {
+ uint32_t const* secType;
+ if (!e->handleAuthentication) continue;
+ for (secType = e->securityTypes; secType && *secType; secType++) {
+ if (authScheme==*secType) {
+ if (!e->handleAuthentication(client, authScheme)) return FALSE;
+ if (!rfbHandleAuthResult(client)) return FALSE;
+ authHandled=TRUE;
+ }
+ }
+ }
+ if (authHandled) break;
+ }
rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
(int)authScheme);
return FALSE;
@@ -1190,8 +1224,12 @@ InitialiseRFBConnection(rfbClient* client)
client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
- /* To guard against integer wrap-around, si.nameLength is cast to 64 bit */
- client->desktopName = malloc((uint64_t)client->si.nameLength + 1);
+ if (client->si.nameLength > 1<<20) {
+ rfbClientErr("Too big desktop name length sent by server: %u B > 1 MB\n", (unsigned int)client->si.nameLength);
+ return FALSE;
+ }
+
+ client->desktopName = malloc(client->si.nameLength + 1);
if (!client->desktopName) {
rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
(unsigned long)client->si.nameLength);
@@ -1249,6 +1287,7 @@ SetFormatAndEncodings(rfbClient* client)
if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
se->type = rfbSetEncodings;
+ se->pad = 0;
se->nEncodings = 0;
if (client->appData.encodingsString) {
@@ -1639,6 +1678,7 @@ SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
+ memset(&ke, 0, sizeof(ke));
ke.type = rfbKeyEvent;
ke.down = down ? 1 : 0;
ke.key = rfbClientSwap32IfLE(key);
@@ -1657,6 +1697,7 @@ SendClientCutText(rfbClient* client, char *str, int len)
if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
+ memset(&cct, 0, sizeof(cct));
cct.type = rfbClientCutText;
cct.length = rfbClientSwap32IfLE(len);
return (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
@@ -1873,7 +1914,7 @@ HandleRFBServerMessage(rfbClient* client)
/* Regardless of cause, do not divide by zero. */
linesToRead = bytesPerLine ? (RFB_BUFFER_SIZE / bytesPerLine) : 0;
- while (h > 0) {
+ while (linesToRead && h > 0) {
if (linesToRead > h)
linesToRead = h;
@@ -2181,10 +2222,17 @@ HandleRFBServerMessage(rfbClient* client)
msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
+ if (msg.sct.length > 1<<20) {
+ rfbClientErr("Ignoring too big cut text length sent by server: %u B > 1 MB\n", (unsigned int)msg.sct.length);
+ return FALSE;
+ }
+
buffer = malloc(msg.sct.length+1);
- if (!ReadFromRFBServer(client, buffer, msg.sct.length))
+ if (!ReadFromRFBServer(client, buffer, msg.sct.length)) {
+ free(buffer);
return FALSE;
+ }
buffer[msg.sct.length] = 0;
@@ -2418,7 +2466,6 @@ PrintPixelFormat(rfbPixelFormat *format)
#define rfbDes rfbClientDes
#define rfbDesKey rfbClientDesKey
#define rfbUseKey rfbClientUseKey
-#define rfbCPKey rfbClientCPKey
#include "vncauth.c"
#include "d3des.c"
diff --git a/libvncclient/sasl.c b/libvncclient/sasl.c
index 0530307..db240c1 100644
--- a/libvncclient/sasl.c
+++ b/libvncclient/sasl.c
@@ -41,6 +41,9 @@
#ifdef WIN32
#undef SOCKET
#include <winsock2.h>
+#ifdef EWOULDBLOCK
+#undef EWOULDBLOCK
+#endif
#define EWOULDBLOCK WSAEWOULDBLOCK
#define socklen_t int
#define close closesocket
diff --git a/libvncclient/sockets.c b/libvncclient/sockets.c
index ed2deef..f042472 100644
--- a/libvncclient/sockets.c
+++ b/libvncclient/sockets.c
@@ -40,6 +40,9 @@
#ifdef WIN32
#undef SOCKET
#include <winsock2.h>
+#ifdef EWOULDBLOCK
+#undef EWOULDBLOCK
+#endif
#define EWOULDBLOCK WSAEWOULDBLOCK
#define close closesocket
#define read(sock,buf,len) recv(sock,buf,len,0)
diff --git a/libvncclient/tight.c b/libvncclient/tight.c
index 64883e5..df01812 100644
--- a/libvncclient/tight.c
+++ b/libvncclient/tight.c
@@ -23,6 +23,8 @@
#ifdef LIBVNCSERVER_HAVE_LIBZ
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
+#include "turbojpeg.h"
+
/*
* tight.c - handle ``tight'' encoding.
*
diff --git a/libvncclient/tls.h b/libvncclient/tls.h
index a5a2ac6..ffcfdeb 100644
--- a/libvncclient/tls.h
+++ b/libvncclient/tls.h
@@ -43,7 +43,7 @@ int ReadFromTLS(rfbClient* client, char *out, unsigned int n);
* It's a wrapper function over gnutls_record_send() and it will be
* blocking call, until all bytes are written or error returned.
*/
-int WriteToTLS(rfbClient* client, char *buf, unsigned int n);
+int WriteToTLS(rfbClient* client, const char *buf, unsigned int n);
/* Free TLS resources */
void FreeTLS(rfbClient* client);
diff --git a/libvncclient/tls_gnutls.c b/libvncclient/tls_gnutls.c
index f146d2a..ec3c450 100644
--- a/libvncclient/tls_gnutls.c
+++ b/libvncclient/tls_gnutls.c
@@ -589,7 +589,7 @@ ReadFromTLS(rfbClient* client, char *out, unsigned int n)
}
int
-WriteToTLS(rfbClient* client, char *buf, unsigned int n)
+WriteToTLS(rfbClient* client, const char *buf, unsigned int n)
{
unsigned int offset = 0;
ssize_t ret;
diff --git a/libvncclient/tls_none.c b/libvncclient/tls_none.c
index 4dfcb27..d436ce9 100644
--- a/libvncclient/tls_none.c
+++ b/libvncclient/tls_none.c
@@ -43,7 +43,7 @@ int ReadFromTLS(rfbClient* client, char *out, unsigned int n)
}
-int WriteToTLS(rfbClient* client, char *buf, unsigned int n)
+int WriteToTLS(rfbClient* client, const char *buf, unsigned int n)
{
rfbClientLog("TLS is not supported.\n");
errno = EINTR;
diff --git a/libvncclient/tls_openssl.c b/libvncclient/tls_openssl.c
index fe60147..e2fadb2 100644
--- a/libvncclient/tls_openssl.c
+++ b/libvncclient/tls_openssl.c
@@ -640,7 +640,7 @@ ReadFromTLS(rfbClient* client, char *out, unsigned int n)
}
int
-WriteToTLS(rfbClient* client, char *buf, unsigned int n)
+WriteToTLS(rfbClient* client, const char *buf, unsigned int n)
{
unsigned int offset = 0;
ssize_t ret;
diff --git a/libvncclient/ultra.c b/libvncclient/ultra.c
index a82e2ed..a287526 100644
--- a/libvncclient/ultra.c
+++ b/libvncclient/ultra.c
@@ -66,6 +66,8 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if ((client->raw_buffer_size % 4)!=0)
client->raw_buffer_size += (4-(client->raw_buffer_size % 4));
client->raw_buffer = (char*) malloc( client->raw_buffer_size );
+ if(client->raw_buffer == NULL)
+ return FALSE;
}
/* allocate enough space to store the incoming compressed packet */
@@ -150,6 +152,8 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh)
if ((client->raw_buffer_size % 4)!=0)
client->raw_buffer_size += (4-(client->raw_buffer_size % 4));
client->raw_buffer = (char*) malloc( client->raw_buffer_size );
+ if(client->raw_buffer == NULL)
+ return FALSE;
}
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c
index 2a13f0e..ec1b73a 100644
--- a/libvncclient/vncviewer.c
+++ b/libvncclient/vncviewer.c
@@ -519,6 +519,12 @@ void rfbClientCleanup(rfbClient* client) {
#endif
#endif
+ if (client->ultra_buffer)
+ free(client->ultra_buffer);
+
+ if (client->raw_buffer)
+ free(client->raw_buffer);
+
FreeTLS(client);
while (client->clientData) {