diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2017-10-14 18:50:54 +0200 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2017-10-14 18:50:54 +0200 |
commit | 68cb29a12f8f2a336088f087cdbc9e0e7aa92ae5 (patch) | |
tree | b1a8739116bd994e85cfa4ac8a275b49678ba00b /libvncserver | |
parent | 27bc3dba7089268b0247e91957fff498a43d08dc (diff) | |
parent | 8415ff4c3517c6697d53e1a17bba35284f480891 (diff) | |
download | libtdevnc-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.am | 12 | ||||
-rw-r--r-- | libvncserver/cargs.c | 2 | ||||
-rw-r--r-- | libvncserver/httpd.c | 30 | ||||
-rw-r--r-- | libvncserver/main.c | 18 | ||||
-rw-r--r-- | libvncserver/rfbcrypto_included.c | 2 | ||||
-rw-r--r-- | libvncserver/rfbserver.c | 29 | ||||
-rw-r--r-- | libvncserver/rfbssl_gnutls.c | 2 | ||||
-rw-r--r-- | libvncserver/scale.c | 4 | ||||
-rw-r--r-- | libvncserver/sockets.c | 155 | ||||
-rw-r--r-- | libvncserver/tight.c | 8 | ||||
-rw-r--r-- | libvncserver/tightvnc-filetransfer/filetransfermsg.c | 4 | ||||
-rw-r--r-- | libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c | 2 | ||||
-rw-r--r-- | libvncserver/tightvnc-filetransfer/rfbtightproto.h | 2 | ||||
-rw-r--r-- | libvncserver/tightvnc-filetransfer/rfbtightserver.c | 2 | ||||
-rw-r--r-- | libvncserver/ultra.c | 2 | ||||
-rw-r--r-- | libvncserver/websockets.c | 58 | ||||
-rw-r--r-- | libvncserver/zlib.c | 2 |
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 |