summaryrefslogtreecommitdiffstats
path: root/libvncserver
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2017-10-14 18:50:54 +0200
committerSlávek Banko <slavek.banko@axis.cz>2017-10-14 18:50:54 +0200
commit68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5 (patch)
treeb1a8739116bd994e85cfa4ac8a275b49678ba00b /libvncserver
parent27bc3dba7089268b0247e91957fff498a43d08dc (diff)
parent8415ff4c3517c6697d53e1a17bba35284f480891 (diff)
downloadlibtdevnc-68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5.tar.gz
libtdevnc-68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5.zip
Merge tag 'LibVNCServer-0.9.11' of https://github.com/LibVNC/libvncserver
Conflicts: CMakeLists.txt libvncserver/main.c
Diffstat (limited to 'libvncserver')
-rw-r--r--libvncserver/Makefile.am12
-rw-r--r--libvncserver/cargs.c2
-rw-r--r--libvncserver/httpd.c30
-rw-r--r--libvncserver/main.c18
-rw-r--r--libvncserver/rfbcrypto_included.c2
-rw-r--r--libvncserver/rfbserver.c29
-rw-r--r--libvncserver/rfbssl_gnutls.c2
-rw-r--r--libvncserver/scale.c4
-rw-r--r--libvncserver/sockets.c155
-rw-r--r--libvncserver/tight.c8
-rw-r--r--libvncserver/tightvnc-filetransfer/filetransfermsg.c4
-rw-r--r--libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c2
-rw-r--r--libvncserver/tightvnc-filetransfer/rfbtightproto.h2
-rw-r--r--libvncserver/tightvnc-filetransfer/rfbtightserver.c2
-rw-r--r--libvncserver/ultra.c2
-rw-r--r--libvncserver/websockets.c58
-rw-r--r--libvncserver/zlib.c2
17 files changed, 214 insertions, 120 deletions
diff --git a/libvncserver/Makefile.am b/libvncserver/Makefile.am
index cb38c64..e25784b 100644
--- a/libvncserver/Makefile.am
+++ b/libvncserver/Makefile.am
@@ -30,14 +30,13 @@ WEBSOCKETSSRCS = websockets.c $(WEBSOCKETSSSLSRCS)
endif
includedir=$(prefix)/include/rfb
-#include_HEADERS=rfb.h rfbconfig.h rfbint.h rfbproto.h keysym.h rfbregion.h
-include_HEADERS=../rfb/rfb.h ../rfb/rfbconfig.h ../rfb/rfbint.h \
+include_HEADERS=../rfb/rfb.h ../rfb/rfbconfig.h \
../rfb/rfbproto.h ../rfb/keysym.h ../rfb/rfbregion.h ../rfb/rfbclient.h
noinst_HEADERS=../common/d3des.h ../rfb/default8x16.h zrleoutstream.h \
zrlepalettehelper.h zrletypes.h private.h scale.h rfbssl.h rfbcrypto.h \
- ../common/minilzo.h ../common/lzoconf.h ../common/lzodefs.h ../common/md5.h ../common/sha1.h \
+ ../common/minilzo.h ../common/lzoconf.h ../common/lzodefs.h ../common/md5.h ../common/sha.h ../common/sha-private.h \
$(TIGHTVNCFILETRANSFERHDRS)
EXTRA_DIST=tableinit24.c tableinittctemplate.c tabletranstemplate.c \
@@ -60,7 +59,14 @@ LIB_SRCS = main.c rfbserver.c rfbregion.c auth.c sockets.c $(WEBSOCKETSSRCS) \
libvncserver_la_SOURCES=$(LIB_SRCS)
libvncserver_la_LIBADD=$(WEBSOCKETSSSLLIBS)
+if WITH_SYSTEMD
+AM_CPPFLAGS += -DLIBVNCSERVER_WITH_SYSTEMD
+libvncserver_la_CFLAGS = $(LIBSYSTEMD_CFLAGS)
+libvncserver_la_LIBADD += $(LIBSYSTEMD_LIBS)
+endif
+
lib_LTLIBRARIES=libvncserver.la
+libvncserver_la_LDFLAGS = -version-info 1:0:0
if HAVE_RPM
$(PACKAGE)-$(VERSION).tar.gz: dist
diff --git a/libvncserver/cargs.c b/libvncserver/cargs.c
index b9eb02b..4da04b5 100644
--- a/libvncserver/cargs.c
+++ b/libvncserver/cargs.c
@@ -1,5 +1,5 @@
/*
- * This parses the command line arguments. It was seperated from main.c by
+ * This parses the command line arguments. It was separated from main.c by
* Justin Dearing <jdeari01@longisland.poly.edu>.
*/
diff --git a/libvncserver/httpd.c b/libvncserver/httpd.c
index 12d71a8..8634b15 100644
--- a/libvncserver/httpd.c
+++ b/libvncserver/httpd.c
@@ -81,9 +81,7 @@
"<HEAD><TITLE>Invalid Request</TITLE></HEAD>\n" \
"<BODY><H1>Invalid request</H1></BODY>\n"
-#define OK_STR "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n"
-#define OK_STR_HTML "HTTP/1.0 200 OK\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n"
-
+#define OK_STR "HTTP/1.0 200 OK\r\nConnection: close\r\n"
static void httpProcessInput(rfbScreenInfoPtr screen);
@@ -192,7 +190,7 @@ rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen)
}
tv.tv_sec = 0;
tv.tv_usec = 0;
- nfds = select(max(rfbScreen->httpListen6Sock, max(rfbScreen->httpSock,rfbScreen->httpListenSock)) + 1, &fds, NULL, NULL, &tv);
+ nfds = select(rfbMax(rfbScreen->httpListen6Sock, rfbMax(rfbScreen->httpSock,rfbScreen->httpListenSock)) + 1, &fds, NULL, NULL, &tv);
if (nfds == 0) {
return;
}
@@ -423,6 +421,14 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
}
}
+ /* Basic protection against directory traversal outside webroot */
+
+ if (strstr(fname, "..")) {
+ rfbErr("httpd: URL should not contain '..'\n");
+ rfbWriteExact(&cl, NOT_FOUND_STR, strlen(NOT_FOUND_STR));
+ httpCloseSock(rfbScreen);
+ return;
+ }
/* If we were asked for '/', actually read the file index.vnc */
@@ -446,10 +452,18 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
return;
}
- if(performSubstitutions) /* is the 'index.vnc' file */
- rfbWriteExact(&cl, OK_STR_HTML, strlen(OK_STR_HTML));
- else
- rfbWriteExact(&cl, OK_STR, strlen(OK_STR));
+ rfbWriteExact(&cl, OK_STR, strlen(OK_STR));
+ char *ext = strrchr(fname, '.');
+ char *contentType = "";
+ if(ext && strcasecmp(ext, ".vnc") == 0)
+ contentType = "Content-Type: text/html\r\n";
+ else if(ext && strcasecmp(ext, ".css") == 0)
+ contentType = "Content-Type: text/css\r\n";
+ else if(ext && strcasecmp(ext, ".svg") == 0)
+ contentType = "Content-Type: image/svg+xml\r\n";
+ rfbWriteExact(&cl, contentType, strlen(contentType));
+ /* end the header */
+ rfbWriteExact(&cl, "\r\n", 2);
while (1) {
int n = fread(buf, 1, BUF_SIZE-1, fd);
diff --git a/libvncserver/main.c b/libvncserver/main.c
index 7340364..4fbe036 100644
--- a/libvncserver/main.c
+++ b/libvncserver/main.c
@@ -579,7 +579,15 @@ clientInput(void *data)
rfbSendFileTransferChunk(cl);
if (FD_ISSET(cl->sock, &rfds) || FD_ISSET(cl->sock, &efds))
+ {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ do {
+ rfbProcessClientMessage(cl);
+ } while (webSocketsHasDataInBuffer(cl));
+#else
rfbProcessClientMessage(cl);
+#endif
+ }
}
/* Get rid of the output thread. */
@@ -616,7 +624,7 @@ listenerRun(void *data)
return NULL;
}
- /* TODO: this thread wont die by restarting the server */
+ /* TODO: this thread won't die by restarting the server */
/* TODO: HTTP is not handled */
while (1) {
client_fd = -1;
@@ -662,7 +670,11 @@ rfbStartOnHoldClient(rfbClientPtr cl)
void
rfbStartOnHoldClient(rfbClientPtr cl)
{
- cl->onHold = FALSE;
+ cl->onHold = FALSE;
+#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
+ if(cl->screen->backgroundLoop)
+ pthread_create(&cl->client_thread, NULL, clientInput, (void *)cl);
+#endif
}
#endif
@@ -1310,4 +1322,4 @@ void ClientOutputHandlerObject::run(void) {
TQThread::exit();
}
-#include "main.moc" \ No newline at end of file
+#include "main.moc"
diff --git a/libvncserver/rfbcrypto_included.c b/libvncserver/rfbcrypto_included.c
index 58c2e93..7feff61 100644
--- a/libvncserver/rfbcrypto_included.c
+++ b/libvncserver/rfbcrypto_included.c
@@ -23,7 +23,7 @@
#include <string.h>
#include "md5.h"
-#include "sha1.h"
+#include "sha.h"
#include "rfbcrypto.h"
void digestmd5(const struct iovec *iov, int iovcnt, void *dest)
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index fbae203..44723ef 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -365,13 +365,11 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen,
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("setsockopt failed");
- close(sock);
- return NULL;
+ rfbLogPerror("setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
}
FD_SET(sock,&(rfbScreen->allFds));
- rfbScreen->maxFd = max(sock,rfbScreen->maxFd);
+ rfbScreen->maxFd = rfbMax(sock,rfbScreen->maxFd);
INIT_MUTEX(cl->outputMutex);
INIT_MUTEX(cl->refCountMutex);
@@ -958,7 +956,6 @@ rfbSendSupportedMessages(rfbClientPtr cl)
/*rfbSetBit(msgs.client2server, rfbSetSW); */
/*rfbSetBit(msgs.client2server, rfbTextChat); */
rfbSetBit(msgs.client2server, rfbPalmVNCSetScaleFactor);
- rfbSetBit(msgs.client2server, rfbXvp);
rfbSetBit(msgs.server2client, rfbFramebufferUpdate);
rfbSetBit(msgs.server2client, rfbSetColourMapEntries);
@@ -966,7 +963,11 @@ rfbSendSupportedMessages(rfbClientPtr cl)
rfbSetBit(msgs.server2client, rfbServerCutText);
rfbSetBit(msgs.server2client, rfbResizeFrameBuffer);
rfbSetBit(msgs.server2client, rfbPalmVNCReSizeFrameBuffer);
- rfbSetBit(msgs.server2client, rfbXvp);
+
+ if (cl->screen->xvpHook) {
+ rfbSetBit(msgs.client2server, rfbXvp);
+ rfbSetBit(msgs.server2client, rfbXvp);
+ }
memcpy(&cl->updateBuf[cl->ublen], (char *)&msgs, sz_rfbSupportedMessages);
cl->ublen += sz_rfbSupportedMessages;
@@ -2225,13 +2226,15 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
cl->enableServerIdentity = TRUE;
}
break;
- case rfbEncodingXvp:
- rfbLog("Enabling Xvp protocol extension for client "
- "%s\n", cl->host);
- if (!rfbSendXvp(cl, 1, rfbXvp_Init)) {
- rfbCloseClient(cl);
- return;
- }
+ case rfbEncodingXvp:
+ if (cl->screen->xvpHook) {
+ rfbLog("Enabling Xvp protocol extension for client "
+ "%s\n", cl->host);
+ if (!rfbSendXvp(cl, 1, rfbXvp_Init)) {
+ rfbCloseClient(cl);
+ return;
+ }
+ }
break;
default:
#if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG)
diff --git a/libvncserver/rfbssl_gnutls.c b/libvncserver/rfbssl_gnutls.c
index cf60cdc..e58cdad 100644
--- a/libvncserver/rfbssl_gnutls.c
+++ b/libvncserver/rfbssl_gnutls.c
@@ -109,6 +109,8 @@ struct rfbssl_ctx *rfbssl_init_global(char *key, char *cert)
gnutls_global_set_log_function(rfbssl_log_func);
gnutls_global_set_log_level(1);
gnutls_certificate_set_dh_params(ctx->x509_cred, ctx->dh_params);
+ /* newly allocated memory should be initialized, at least where it is important */
+ ctx->peekstart = ctx->peeklen = 0;
return ctx;
}
diff --git a/libvncserver/scale.c b/libvncserver/scale.c
index d11db40..3ca76dc 100644
--- a/libvncserver/scale.c
+++ b/libvncserver/scale.c
@@ -213,7 +213,7 @@ void rfbScaledScreenUpdateRect(rfbScreenInfoPtr screen, rfbScreenInfoPtr ptr, in
case 2: pixel_value = *((unsigned short *)srcptr2); break;
case 1: pixel_value = *((unsigned char *)srcptr2); break;
default:
- /* fixme: endianess problem? */
+ /* fixme: endianness problem? */
for (z = 0; z < bytesPerPixel; z++)
pixel_value += (srcptr2[z] << (8 * z));
break;
@@ -240,7 +240,7 @@ void rfbScaledScreenUpdateRect(rfbScreenInfoPtr screen, rfbScreenInfoPtr ptr, in
case 2: *((unsigned short *)dstptr) = (unsigned short) pixel_value; break;
case 1: *((unsigned char *)dstptr) = (unsigned char) pixel_value; break;
default:
- /* fixme: endianess problem? */
+ /* fixme: endianness problem? */
for (z = 0; z < bytesPerPixel; z++)
dstptr[z]=(pixel_value >> (8 * z)) & 0xff;
break;
diff --git a/libvncserver/sockets.c b/libvncserver/sockets.c
index a9c5a2c..bbc3d90 100644
--- a/libvncserver/sockets.c
+++ b/libvncserver/sockets.c
@@ -77,6 +77,10 @@
#include "rfbssl.h"
#endif
+#ifdef LIBVNCSERVER_WITH_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
#if defined(__linux__) && defined(NEED_TIMEVAL)
struct timeval
{
@@ -122,6 +126,54 @@ int deny_severity=LOG_WARNING;
int rfbMaxClientWait = 20000; /* time (ms) after which we decide client has
gone away - needed to stop us hanging */
+static rfbBool
+rfbNewConnectionFromSock(rfbScreenInfoPtr rfbScreen, int sock)
+{
+ const int one = 1;
+#ifdef LIBVNCSERVER_IPv6
+ struct sockaddr_storage addr;
+#else
+ struct sockaddr_in addr;
+#endif
+ socklen_t addrlen = sizeof(addr);
+
+ getpeername(sock, (struct sockaddr *)&addr, &addrlen);
+
+ if(!rfbSetNonBlocking(sock)) {
+ rfbLogPerror("rfbCheckFds: setnonblock");
+ closesocket(sock);
+ return FALSE;
+ }
+
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+ (char *)&one, sizeof(one)) < 0) {
+ rfbLogPerror("rfbCheckFds: setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
+ }
+
+#ifdef USE_LIBWRAP
+ if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
+ STRING_UNKNOWN)) {
+ rfbLog("Rejected connection from client %s\n",
+ inet_ntoa(addr.sin_addr));
+ closesocket(sock);
+ return FALSE;
+ }
+#endif
+
+#ifdef LIBVNCSERVER_IPv6
+ char host[1024];
+ if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
+ rfbLogPerror("rfbProcessNewConnection: error in getnameinfo");
+ }
+ rfbLog("Got connection from client %s\n", host);
+#else
+ rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
+#endif
+
+ rfbNewClient(rfbScreen,sock);
+ return TRUE;
+}
+
/*
* rfbInitSockets sets up the TCP and UDP sockets to listen for RFB
* connections. It does nothing if called again.
@@ -138,6 +190,20 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
rfbScreen->socketState = RFB_SOCKET_READY;
+#ifdef LIBVNCSERVER_WITH_SYSTEMD
+ if (sd_listen_fds(0) == 1)
+ {
+ int sock = SD_LISTEN_FDS_START + 0;
+ if (sd_is_socket(sock, AF_UNSPEC, 0, 0))
+ rfbNewConnectionFromSock(rfbScreen, sock);
+ else if (sd_is_socket(sock, AF_UNSPEC, 0, 1))
+ rfbProcessNewConnection(rfbScreen);
+ return;
+ }
+ else
+ rfbLog("Unable to establish connection with systemd socket\n");
+#endif
+
if (rfbScreen->inetdSock != -1) {
const int one = 1;
@@ -146,8 +212,7 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
if (setsockopt(rfbScreen->inetdSock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("setsockopt");
- return;
+ rfbLogPerror("setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
}
FD_ZERO(&(rfbScreen->allFds));
@@ -156,10 +221,10 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
return;
}
- if(rfbScreen->autoPort) {
- int i;
- FD_ZERO(&(rfbScreen->allFds));
+ FD_ZERO(&(rfbScreen->allFds));
+ if(rfbScreen->autoPort && rfbScreen->port>0) {
+ int i;
rfbLog("Autoprobing TCP port \n");
for (i = 5900; i < 6000; i++) {
if ((rfbScreen->listenSock = rfbListenOnTCPPort(i, iface)) >= 0) {
@@ -176,8 +241,11 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
rfbLog("Autoprobing selected TCP port %d\n", rfbScreen->port);
FD_SET(rfbScreen->listenSock, &(rfbScreen->allFds));
rfbScreen->maxFd = rfbScreen->listenSock;
+ }
#ifdef LIBVNCSERVER_IPv6
+ if(rfbScreen->autoPort && rfbScreen->ipv6port>0) {
+ int i;
rfbLog("Autoprobing TCP6 port \n");
for (i = 5900; i < 6000; i++) {
if ((rfbScreen->listen6Sock = rfbListenOnTCP6Port(i, rfbScreen->listen6Interface)) >= 0) {
@@ -193,13 +261,12 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
rfbLog("Autoprobing selected TCP6 port %d\n", rfbScreen->ipv6port);
FD_SET(rfbScreen->listen6Sock, &(rfbScreen->allFds));
- rfbScreen->maxFd = max((int)rfbScreen->listen6Sock,rfbScreen->maxFd);
-#endif
+ rfbScreen->maxFd = rfbMax((int)rfbScreen->listen6Sock,rfbScreen->maxFd);
}
- else
- {
+#endif
+
+ if(!rfbScreen->autoPort) {
if(rfbScreen->port>0) {
- FD_ZERO(&(rfbScreen->allFds));
if ((rfbScreen->listenSock = rfbListenOnTCPPort(rfbScreen->port, iface)) < 0) {
rfbLogPerror("ListenOnTCPPort");
@@ -220,7 +287,7 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
rfbLog("Listening for VNC connections on TCP6 port %d\n", rfbScreen->ipv6port);
FD_SET(rfbScreen->listen6Sock, &(rfbScreen->allFds));
- rfbScreen->maxFd = max((int)rfbScreen->listen6Sock,rfbScreen->maxFd);
+ rfbScreen->maxFd = rfbMax((int)rfbScreen->listen6Sock,rfbScreen->maxFd);
}
#endif
@@ -236,7 +303,7 @@ rfbInitSockets(rfbScreenInfoPtr rfbScreen)
rfbLog("Listening for VNC connections on TCP port %d\n", rfbScreen->port);
FD_SET(rfbScreen->udpSock, &(rfbScreen->allFds));
- rfbScreen->maxFd = max((int)rfbScreen->udpSock,rfbScreen->maxFd);
+ rfbScreen->maxFd = rfbMax((int)rfbScreen->udpSock,rfbScreen->maxFd);
}
}
@@ -391,7 +458,15 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
{
if (FD_ISSET(cl->sock, &fds))
+ {
+#ifdef LIBVNCSERVER_WITH_WEBSOCKETS
+ do {
+ rfbProcessClientMessage(cl);
+ } while (cl->sock > 0 && webSocketsHasDataInBuffer(cl));
+#else
rfbProcessClientMessage(cl);
+#endif
+ }
else
rfbSendFileTransferChunk(cl);
}
@@ -404,14 +479,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
rfbBool
rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
{
- const int one = 1;
int sock = -1;
-#ifdef LIBVNCSERVER_IPv6
- struct sockaddr_storage addr;
-#else
- struct sockaddr_in addr;
-#endif
- socklen_t addrlen = sizeof(addr);
fd_set listen_fds;
int chosen_listen_sock = -1;
@@ -432,49 +500,12 @@ rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen)
if (rfbScreen->listen6Sock >= 0 && FD_ISSET(rfbScreen->listen6Sock, &listen_fds))
chosen_listen_sock = rfbScreen->listen6Sock;
- if ((sock = accept(chosen_listen_sock,
- (struct sockaddr *)&addr, &addrlen)) < 0) {
+ if ((sock = accept(chosen_listen_sock, NULL, NULL)) < 0) {
rfbLogPerror("rfbCheckFds: accept");
return FALSE;
}
- if(!rfbSetNonBlocking(sock)) {
- closesocket(sock);
- return FALSE;
- }
-
- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
- (char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("rfbCheckFds: setsockopt");
- closesocket(sock);
- return FALSE;
- }
-
-#ifdef USE_LIBWRAP
- if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
- STRING_UNKNOWN)) {
- rfbLog("Rejected connection from client %s\n",
- inet_ntoa(addr.sin_addr));
- closesocket(sock);
- return FALSE;
- }
-#endif
-
-#ifdef LIBVNCSERVER_IPv6
- {
- char host[1024];
- if(getnameinfo((struct sockaddr*)&addr, addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST) != 0) {
- rfbLogPerror("rfbProcessNewConnection: error in getnameinfo");
- }
- rfbLog("Got connection from client %s\n", host);
- }
-#else
- rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));
-#endif
-
- rfbNewClient(rfbScreen,sock);
-
- return TRUE;
+ return rfbNewConnectionFromSock(rfbScreen, sock);
}
@@ -548,14 +579,12 @@ rfbConnect(rfbScreenInfoPtr rfbScreen,
if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
(char *)&one, sizeof(one)) < 0) {
- rfbLogPerror("setsockopt failed");
- closesocket(sock);
- return -1;
+ rfbLogPerror("setsockopt failed: can't set TCP_NODELAY flag, non TCP socket?");
}
/* AddEnabledDevice(sock); */
FD_SET(sock, &rfbScreen->allFds);
- rfbScreen->maxFd = max(sock,rfbScreen->maxFd);
+ rfbScreen->maxFd = rfbMax(sock,rfbScreen->maxFd);
return sock;
}
@@ -917,7 +946,7 @@ rfbListenOnTCP6Port(int port,
}
#ifdef IPV6_V6ONLY
- /* we have seperate IPv4 and IPv6 sockets since some OS's do not support dual binding */
+ /* we have separate IPv4 and IPv6 sockets since some OS's do not support dual binding */
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) {
rfbLogPerror("rfbListenOnTCP6Port error in setsockopt IPV6_V6ONLY");
closesocket(sock);
diff --git a/libvncserver/tight.c b/libvncserver/tight.c
index 276a2e3..bca374d 100644
--- a/libvncserver/tight.c
+++ b/libvncserver/tight.c
@@ -163,7 +163,11 @@ void rfbTightCleanup (rfbScreenInfoPtr screen)
tightAfterBufSize = 0;
tightAfterBuf = NULL;
}
- if (j) tjDestroy(j);
+ if (j) {
+ tjDestroy(j);
+ /* Set freed resource handle to 0! */
+ j = 0;
+ }
}
@@ -559,7 +563,7 @@ ExtendSolidArea(rfbClientPtr cl,
/*
* Check if a rectangle is all of the same color. If needSameColor is
* set to non-zero, then also check that its color equals to the
- * *colorPtr value. The result is 1 if the test is successfull, and in
+ * *colorPtr value. The result is 1 if the test is successful, and in
* that case new color will be stored in *colorPtr.
*/
diff --git a/libvncserver/tightvnc-filetransfer/filetransfermsg.c b/libvncserver/tightvnc-filetransfer/filetransfermsg.c
index 88fbe9a..153f123 100644
--- a/libvncserver/tightvnc-filetransfer/filetransfermsg.c
+++ b/libvncserver/tightvnc-filetransfer/filetransfermsg.c
@@ -108,8 +108,8 @@ GetFileListResponseMsg(char* path, char flags)
/* fileListInfo can have null data if the folder is Empty
- or if some error condition has occured.
- The return value is 'failure' only if some error condition has occured.
+ or if some error condition has occurred.
+ The return value is 'failure' only if some error condition has occurred.
*/
status = CreateFileListInfo(&fileListInfo, path, !(flags & 0x10));
diff --git a/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c b/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c
index 431912e..b235fa0 100644
--- a/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c
+++ b/libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c
@@ -703,7 +703,7 @@ HandleFileUploadLengthError(rfbClientPtr cl, short fNameSize)
return;
}
- rfbLog("File [%s]: Method [%s]: File Upload Length Error occured"
+ rfbLog("File [%s]: Method [%s]: File Upload Length Error occurred"
"file path requested is <%s>\n", __FILE__, __FUNCTION__, path);
if(path != NULL) {
diff --git a/libvncserver/tightvnc-filetransfer/rfbtightproto.h b/libvncserver/tightvnc-filetransfer/rfbtightproto.h
index ef683ae..d0fe642 100644
--- a/libvncserver/tightvnc-filetransfer/rfbtightproto.h
+++ b/libvncserver/tightvnc-filetransfer/rfbtightproto.h
@@ -208,7 +208,7 @@ void rfbHandleSecTypeTight(rfbClientPtr cl);
* In the protocol version 3.7t, the server informs the client what message
* types it supports in addition to ones defined in the protocol version 3.7.
* Also, the server sends the list of all supported encodings (note that it's
- * not necessary to advertise the "raw" encoding sinse it MUST be supported in
+ * not necessary to advertise the "raw" encoding since it MUST be supported in
* RFB 3.x protocols).
*
* This data immediately follows the server initialisation message.
diff --git a/libvncserver/tightvnc-filetransfer/rfbtightserver.c b/libvncserver/tightvnc-filetransfer/rfbtightserver.c
index d43d3f3..67d4cb5 100644
--- a/libvncserver/tightvnc-filetransfer/rfbtightserver.c
+++ b/libvncserver/tightvnc-filetransfer/rfbtightserver.c
@@ -500,7 +500,7 @@ rfbHandleSecTypeTight(rfbClientPtr cl) {
if(rtcp == NULL) {
/* Error condition close socket */
- rfbLog("Memory error has occured while handling "
+ rfbLog("Memory error has occurred while handling "
"Tight security type... closing connection.\n");
rfbCloseClient(cl);
return;
diff --git a/libvncserver/ultra.c b/libvncserver/ultra.c
index 9485591..83bddaa 100644
--- a/libvncserver/ultra.c
+++ b/libvncserver/ultra.c
@@ -201,7 +201,7 @@ rfbSendRectEncodingUltra(rfbClientPtr cl,
return FALSE;
}
- /* Technically, flushing the buffer here is not extrememly
+ /* Technically, flushing the buffer here is not extremely
* efficient. However, this improves the overall throughput
* of the system over very slow networks. By flushing
* the buffer with every maximum size lzo rectangle, we
diff --git a/libvncserver/websockets.c b/libvncserver/websockets.c
index 34f04d7..bdec8f3 100644
--- a/libvncserver/websockets.c
+++ b/libvncserver/websockets.c
@@ -79,8 +79,9 @@ typedef int (*wsEncodeFunc)(rfbClientPtr cl, const char *src, int len, char **ds
typedef int (*wsDecodeFunc)(rfbClientPtr cl, char *dst, int len);
typedef struct ws_ctx_s {
- char codeBuf[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */
- char readbuf[8192];
+ char codeBufDecode[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */
+ char codeBufEncode[B64LEN(UPDATE_BUF_SIZE) + WSHLENMAX]; /* base64 + maximum frame header length */
+ char readbuf[8192];
int readbufstart;
int readbuflen;
int dblen;
@@ -152,6 +153,11 @@ Sec-WebSocket-Accept: %s\r\n\
Sec-WebSocket-Protocol: %s\r\n\
\r\n"
+#define SERVER_HANDSHAKE_HYBI_NO_PROTOCOL "HTTP/1.1 101 Switching Protocols\r\n\
+Upgrade: websocket\r\n\
+Connection: Upgrade\r\n\
+Sec-WebSocket-Accept: %s\r\n\
+\r\n"
#define WEBSOCKETS_CLIENT_CONNECT_WAIT_MS 100
#define WEBSOCKETS_CLIENT_SEND_WAIT_MS 100
@@ -389,8 +395,12 @@ webSocketsHandshake(rfbClientPtr cl, char *scheme)
char accept[B64LEN(SHA1_HASH_SIZE) + 1];
rfbLog(" - WebSockets client version hybi-%02d\n", sec_ws_version);
webSocketsGenSha1Key(accept, sizeof(accept), sec_ws_key);
- len = snprintf(response, WEBSOCKETS_MAX_HANDSHAKE_LEN,
- SERVER_HANDSHAKE_HYBI, accept, protocol);
+ if(strlen(protocol) > 0)
+ len = snprintf(response, WEBSOCKETS_MAX_HANDSHAKE_LEN,
+ SERVER_HANDSHAKE_HYBI, accept, protocol);
+ else
+ len = snprintf(response, WEBSOCKETS_MAX_HANDSHAKE_LEN,
+ SERVER_HANDSHAKE_HYBI_NO_PROTOCOL, accept);
} else {
/* older hixie handshake, this could be removed if
* a final standard is established */
@@ -490,15 +500,15 @@ webSocketsEncodeHixie(rfbClientPtr cl, const char *src, int len, char **dst)
int sz = 0;
ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;
- wsctx->codeBuf[sz++] = '\x00';
- len = __b64_ntop((unsigned char *)src, len, wsctx->codeBuf+sz, sizeof(wsctx->codeBuf) - (sz + 1));
+ wsctx->codeBufEncode[sz++] = '\x00';
+ len = __b64_ntop((unsigned char *)src, len, wsctx->codeBufEncode+sz, sizeof(wsctx->codeBufEncode) - (sz + 1));
if (len < 0) {
return len;
}
sz += len;
- wsctx->codeBuf[sz++] = '\xff';
- *dst = wsctx->codeBuf;
+ wsctx->codeBufEncode[sz++] = '\xff';
+ *dst = wsctx->codeBufEncode;
return sz;
}
@@ -536,7 +546,7 @@ webSocketsDecodeHixie(rfbClientPtr cl, char *dst, int len)
char *buf, *end = NULL;
ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;
- buf = wsctx->codeBuf;
+ buf = wsctx->codeBufDecode;
n = ws_peek(cl, buf, len*2+2);
@@ -657,8 +667,8 @@ webSocketsDecodeHybi(rfbClientPtr cl, char *dst, int len)
goto spor;
}
- buf = wsctx->codeBuf;
- header = (ws_header_t *)wsctx->codeBuf;
+ buf = wsctx->codeBufDecode;
+ header = (ws_header_t *)wsctx->codeBufDecode;
ret = ws_peek(cl, buf, B64LEN(len) + WSHLENMAX);
@@ -742,11 +752,11 @@ webSocketsDecodeHybi(rfbClientPtr cl, char *dst, int len)
errno = ECONNRESET;
break;
case WS_OPCODE_TEXT_FRAME:
- if (-1 == (flength = __b64_pton(payload, (unsigned char *)wsctx->codeBuf, sizeof(wsctx->codeBuf)))) {
+ if (-1 == (flength = __b64_pton(payload, (unsigned char *)wsctx->codeBufDecode, sizeof(wsctx->codeBufDecode)))) {
rfbErr("%s: Base64 decode error; %m\n", __func__);
break;
}
- payload = wsctx->codeBuf;
+ payload = wsctx->codeBufDecode;
/* fall through */
case WS_OPCODE_BINARY_FRAME:
if (flength > len) {
@@ -790,7 +800,7 @@ webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst)
return 0;
}
- header = (ws_header_t *)wsctx->codeBuf;
+ header = (ws_header_t *)wsctx->codeBufEncode;
if (wsctx->base64) {
opcode = WS_OPCODE_TEXT_FRAME;
@@ -816,7 +826,7 @@ webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst)
}
if (wsctx->base64) {
- if (-1 == (ret = __b64_ntop((unsigned char *)src, len, wsctx->codeBuf + sz, sizeof(wsctx->codeBuf) - sz))) {
+ if (-1 == (ret = __b64_ntop((unsigned char *)src, len, wsctx->codeBufEncode + sz, sizeof(wsctx->codeBufEncode) - sz))) {
rfbErr("%s: Base 64 encode failed\n", __func__);
} else {
if (ret != blen)
@@ -824,11 +834,12 @@ webSocketsEncodeHybi(rfbClientPtr cl, const char *src, int len, char **dst)
ret += sz;
}
} else {
- memcpy(wsctx->codeBuf + sz, src, len);
+ memcpy(wsctx->codeBufEncode + sz, src, len);
ret = sz + len;
}
- *dst = wsctx->codeBuf;
+ *dst = wsctx->codeBufEncode;
+
return ret;
}
@@ -905,3 +916,16 @@ webSocketCheckDisconnect(rfbClientPtr cl)
return FALSE;
}
+/* returns TRUE if there is data waiting to be read in our internal buffer
+ * or if is there any pending data in the buffer of the SSL implementation
+ */
+rfbBool
+webSocketsHasDataInBuffer(rfbClientPtr cl)
+{
+ ws_ctx_t *wsctx = (ws_ctx_t *)cl->wsctx;
+
+ if (wsctx && wsctx->readbuflen)
+ return TRUE;
+
+ return (cl->sslctx && rfbssl_pending(cl) > 0);
+}
diff --git a/libvncserver/zlib.c b/libvncserver/zlib.c
index ac20c9c..45a1314 100644
--- a/libvncserver/zlib.c
+++ b/libvncserver/zlib.c
@@ -300,7 +300,7 @@ rfbSendRectEncodingZlib(rfbClientPtr cl,
return FALSE;
}
- /* Technically, flushing the buffer here is not extrememly
+ /* Technically, flushing the buffer here is not extremely
* efficient. However, this improves the overall throughput
* of the system over very slow networks. By flushing
* the buffer with every maximum size zlib rectangle, we