From 9f0a1a3bc16d26420c703c6e6cc0f18bd4f6b81e Mon Sep 17 00:00:00 2001 From: dscho Date: Mon, 28 Jul 2003 00:57:52 +0000 Subject: [PATCH] synced with TightVNC and RealVNC --- ChangeLog | 7 ++++ TODO | 21 ++++++---- main.c | 10 ++++- rfb/rfb.h | 7 ++++ rfb/rfbregion.h | 2 + rfbregion.c | 33 +++++++++++++++ rfbserver.c | 106 ++++++++++++++++++++++++++++-------------------- sockets.c | 3 ++ tight.c | 21 ++++++---- vncauth.c | 8 +++- 10 files changed, 156 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index 469b967..ad82706 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ + checked sync with TightVNC 1.2.8: + viewonly/full passwords; if given a list, only the first is a full one + vncRandomBytes is a little more secure now + new weights for tight encoding + checked sync with RealVNC 3.3.7 + introduced maxRectsPerUpdate added first alpha version of LibVNCClient added simple and simple15 example (really simple examples) finally got around to fix configure in CVS @@ -20,6 +26,7 @@ more portable way to determine endianness and types of a given size through autoconf based methods 0.5 + rpm packaging through autoconf autoconf'ed the whole package (including optional support for zlib, pthreads and libjpeg as well as zrle/c++) moved appropriate files to contrib/ and examples/ respectively diff --git a/TODO b/TODO index 8811e0c..ef09115 100644 --- a/TODO +++ b/TODO @@ -1,20 +1,14 @@ immediate: ---------- -x11vnc: clipboard, cursor +TightVNC encoding!!! Regression!!! extra_bytes in rfbDrawCharWithClip. tested mouse buttons make copy rect, but text is not marked as mod. -cursor drawing: set optional grain to mark bigger rectangles as drawn (else - you end up with thousands of one-pixel-rectangles to encode). -selectbox: scroll bars -documentation - hint that to mark very tiny regions as - modified is possibly inefficient for the encodings. - (a trail of points could better be a small rectangle). later: ------ +selectbox: scroll bars authentification schemes (secure vnc) IO function ptr exists; now explain how to tunnel and implement a client address restriction scheme. @@ -24,6 +18,17 @@ CORBA done: ----- +.following two items overridden by RealVNC's idea: if there are too many + rectangles (like >50), just use the bounding box. + cursor drawing: set optional grain to mark bigger rectangles as drawn (else + you end up with thousands of one-pixel-rectangles to encode). + documentation + hint that to mark very tiny regions as + modified is possibly inefficient for the encodings. + (a trail of points could better be a small rectangle). + +.viewonly/full password method +.x11vnc: clipboard, cursor (Karl's work) .autoconf also CARD8,CARD16,... .autoconf .internal HTTP tunnelling feature (needs a special GET target and a few diff --git a/main.c b/main.c index c2d6bc3..5e8a24d 100644 --- a/main.c +++ b/main.c @@ -467,12 +467,16 @@ Bool defaultPasswordCheck(rfbClientPtr cl,const char* response,int len) Bool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len) { char **passwds; + int i=0; - for(passwds=(char**)cl->screen->rfbAuthPasswdData;*passwds;passwds++) { + for(passwds=(char**)cl->screen->rfbAuthPasswdData;*passwds;passwds++,i++) { vncEncryptBytes(cl->authChallenge, *passwds); - if (memcmp(cl->authChallenge, response, len) == 0) + if (memcmp(cl->authChallenge, response, len) == 0) { + if(i>=cl->screen->rfbAuthPasswdFirstViewOnly) + cl->viewOnly=TRUE; return(TRUE); + } } rfbLog("rfbAuthProcessClientMessage: authentication failed from %s\n", @@ -574,6 +578,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, rfbScreen->rfbNeverShared = FALSE; rfbScreen->rfbDontDisconnect = FALSE; rfbScreen->rfbAuthPasswdData = 0; + rfbScreen->rfbAuthPasswdFirstViewOnly = 1; rfbScreen->width = width; rfbScreen->height = height; @@ -611,6 +616,7 @@ rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, IF_PTHREADS(rfbScreen->backgroundLoop = FALSE); rfbScreen->rfbDeferUpdateTime=5; + rfbScreen->maxRectsPerUpdate=50; /* proc's and hook's */ diff --git a/rfb/rfb.h b/rfb/rfb.h index a76d955..a55f34a 100644 --- a/rfb/rfb.h +++ b/rfb/rfb.h @@ -232,7 +232,12 @@ typedef struct _rfbScreenInfo PasswordCheckProcPtr passwordCheck; void* rfbAuthPasswdData; + /* If rfbAuthPasswdData is given a list, this is the first + view only password. */ + int rfbAuthPasswdFirstViewOnly; + /* send only this many rectangles in one update */ + int maxRectsPerUpdate; /* this is the amount of milliseconds to wait at least before sending * an update. */ int rfbDeferUpdateTime; @@ -329,6 +334,8 @@ typedef struct _rfbClientRec { int preferredEncoding; int correMaxWidth, correMaxHeight; + Bool viewOnly; + /* The following member is only used during VNC authentication */ uint8_t authChallenge[CHALLENGESIZE]; diff --git a/rfb/rfbregion.h b/rfb/rfbregion.h index 1bbedf6..95f73e2 100755 --- a/rfb/rfbregion.h +++ b/rfb/rfbregion.h @@ -37,6 +37,8 @@ extern Bool sraRgnPopRect(sraRegion *region, sraRect *rect, extern unsigned long sraRgnCountRects(const sraRegion *rgn); extern Bool sraRgnEmpty(const sraRegion *rgn); +extern sraRegion *sraRgnBBox(const sraRegion *src); + /* -=- rectangle iterator */ typedef struct sraRectangleIterator { diff --git a/rfbregion.c b/rfbregion.c index 59b76c5..d3e241a 100755 --- a/rfbregion.c +++ b/rfbregion.c @@ -582,6 +582,39 @@ sraRgnOffset(sraRegion *dst, int dx, int dy) { } } +sraRegion *sraRgnBBox(const sraRegion *src) { + int xmin=((unsigned int)(int)-1)>>1,ymin=xmin,xmax=1-xmin,ymax=xmax; + sraSpan *vcurr, *hcurr; + + if(!src) + return sraRgnCreate(); + + vcurr = ((sraSpanList*)src)->front._next; + while (vcurr != &(((sraSpanList*)src)->back)) { + if(vcurr->startstart; + if(vcurr->end>ymax) + ymax=vcurr->end; + + hcurr = vcurr->subspan->front._next; + while (hcurr != &(vcurr->subspan->back)) { + if(hcurr->startstart; + if(hcurr->end>xmax) + xmax=hcurr->end; + fprintf(stderr,"%d,%d,%d,%d\n",hcurr->start,vcurr->start,hcurr->end,vcurr->end); + hcurr = hcurr->_next; + } + + vcurr = vcurr->_next; + } + + if(xmaxscreen = rfbScreen; cl->sock = sock; + cl->viewOnly = FALSE; + rfbResetStats(cl); if(isUDP) { @@ -932,70 +934,78 @@ rfbProcessClientNormalMessage(cl) case rfbKeyEvent: - cl->rfbKeyEventsRcvd++; + cl->rfbKeyEventsRcvd++; - if ((n = ReadExact(cl, ((char *)&msg) + 1, - sz_rfbKeyEventMsg - 1)) <= 0) { - if (n != 0) - rfbLogPerror("rfbProcessClientNormalMessage: read"); - rfbCloseClient(cl); - return; - } + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbKeyEventMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } + + if(!cl->viewOnly) { + cl->screen->kbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl); + } - cl->screen->kbdAddEvent(msg.ke.down, (KeySym)Swap32IfLE(msg.ke.key), cl); return; case rfbPointerEvent: - cl->rfbPointerEventsRcvd++; + cl->rfbPointerEventsRcvd++; - if ((n = ReadExact(cl, ((char *)&msg) + 1, - sz_rfbPointerEventMsg - 1)) <= 0) { - if (n != 0) - rfbLogPerror("rfbProcessClientNormalMessage: read"); - rfbCloseClient(cl); - return; - } + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbPointerEventMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } - if (pointerClient && (pointerClient != cl)) - return; + if (pointerClient && (pointerClient != cl)) + return; - if (msg.pe.buttonMask == 0) - pointerClient = NULL; - else - pointerClient = cl; + if (msg.pe.buttonMask == 0) + pointerClient = NULL; + else + pointerClient = cl; + + if(!cl->viewOnly) { + cl->screen->ptrAddEvent(msg.pe.buttonMask, + Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); + } - cl->screen->ptrAddEvent(msg.pe.buttonMask, - Swap16IfLE(msg.pe.x), Swap16IfLE(msg.pe.y), cl); return; case rfbClientCutText: - if ((n = ReadExact(cl, ((char *)&msg) + 1, - sz_rfbClientCutTextMsg - 1)) <= 0) { - if (n != 0) - rfbLogPerror("rfbProcessClientNormalMessage: read"); - rfbCloseClient(cl); - return; - } + if ((n = ReadExact(cl, ((char *)&msg) + 1, + sz_rfbClientCutTextMsg - 1)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + rfbCloseClient(cl); + return; + } - msg.cct.length = Swap32IfLE(msg.cct.length); + if(!cl->viewOnly) { + msg.cct.length = Swap32IfLE(msg.cct.length); - str = (char *)malloc(msg.cct.length); + str = (char *)malloc(msg.cct.length); - if ((n = ReadExact(cl, str, msg.cct.length)) <= 0) { - if (n != 0) - rfbLogPerror("rfbProcessClientNormalMessage: read"); - free(str); - rfbCloseClient(cl); - return; - } + if ((n = ReadExact(cl, str, msg.cct.length)) <= 0) { + if (n != 0) + rfbLogPerror("rfbProcessClientNormalMessage: read"); + free(str); + rfbCloseClient(cl); + return; + } - cl->screen->setXCutText(str, msg.cct.length, cl); + cl->screen->setXCutText(str, msg.cct.length, cl); + free(str); + } - free(str); return; @@ -1166,6 +1176,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion) nUpdateRegionRects += (((w-1) / cl->correMaxWidth + 1) * ((h-1) / cl->correMaxHeight + 1)); } + sraRgnReleaseIterator(i); #ifdef HAVE_LIBZ } else if (cl->preferredEncoding == rfbEncodingZlib) { nUpdateRegionRects = 0; @@ -1193,6 +1204,7 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion) } nUpdateRegionRects += n; } + sraRgnReleaseIterator(i); #endif #endif } else { @@ -1201,6 +1213,14 @@ rfbSendFramebufferUpdate(cl, givenUpdateRegion) fu->type = rfbFramebufferUpdate; if (nUpdateRegionRects != 0xFFFF) { + if(cl->screen->maxRectsPerUpdate>0 + && nUpdateRegionRects>cl->screen->maxRectsPerUpdate) { + sraRegion* newUpdateRegion = sraRgnBBox(updateRegion); + sraRgnDestroy(updateRegion); + updateRegion = newUpdateRegion; + nUpdateRegionRects = sraRgnCountRects(updateRegion); + } + fu->nRects = Swap16IfLE((uint16_t)(sraRgnCountRects(updateCopyRegion) + nUpdateRegionRects + !!sendCursorShape + !!sendCursorPos)); diff --git a/sockets.c b/sockets.c index 3095ec0..c1720a5 100644 --- a/sockets.c +++ b/sockets.c @@ -521,6 +521,7 @@ ListenOnTCPPort(port) int sock; int one = 1; + memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); /* addr.sin_addr.s_addr = interface.s_addr; */ @@ -555,6 +556,7 @@ ConnectToTcpAddr(host, port) int sock; struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); @@ -587,6 +589,7 @@ ListenOnUDPPort(port) int sock; int one = 1; + memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); /* addr.sin_addr.s_addr = interface.s_addr; */ diff --git a/tight.c b/tight.c index cdc0495..7bb7c69 100644 --- a/tight.c +++ b/tight.c @@ -67,13 +67,13 @@ typedef struct TIGHT_CONF_s { } TIGHT_CONF; static TIGHT_CONF tightConf[10] = { - { 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 20, 10000, 23000 }, - { 2048, 128, 6, 65536, 1, 1, 1, 0, 0, 0, 8, 30, 8000, 18000 }, - { 6144, 256, 8, 65536, 3, 3, 2, 0, 0, 0, 24, 40, 6500, 15000 }, - { 10240, 1024, 12, 65536, 5, 5, 3, 0, 0, 0, 32, 50, 5000, 12000 }, - { 16384, 2048, 12, 65536, 6, 6, 4, 0, 0, 0, 32, 55, 4000, 10000 }, - { 32768, 2048, 12, 4096, 7, 7, 5, 4, 150, 380, 32, 60, 3000, 8000 }, - { 65536, 2048, 16, 4096, 7, 7, 6, 4, 170, 420, 48, 65, 2000, 5000 }, + { 512, 32, 6, 65536, 0, 0, 0, 0, 0, 0, 4, 5, 10000, 23000 }, + { 2048, 128, 6, 65536, 1, 1, 1, 0, 0, 0, 8, 10, 8000, 18000 }, + { 6144, 256, 8, 65536, 3, 3, 2, 0, 0, 0, 24, 15, 6500, 15000 }, + { 10240, 1024, 12, 65536, 5, 5, 3, 0, 0, 0, 32, 25, 5000, 12000 }, + { 16384, 2048, 12, 65536, 6, 6, 4, 0, 0, 0, 32, 37, 4000, 10000 }, + { 32768, 2048, 12, 4096, 7, 7, 5, 4, 150, 380, 32, 50, 3000, 8000 }, + { 65536, 2048, 16, 4096, 7, 7, 6, 4, 170, 420, 48, 60, 2000, 5000 }, { 65536, 2048, 16, 4096, 8, 8, 7, 5, 180, 450, 64, 70, 1000, 2500 }, { 65536, 2048, 32, 8192, 9, 9, 8, 6, 190, 475, 64, 75, 500, 1200 }, { 65536, 2048, 32, 8192, 9, 9, 9, 6, 200, 500, 96, 80, 200, 500 } @@ -432,6 +432,13 @@ ExtendSolidArea(cl, x, y, w, h, colorValue, x_ptr, y_ptr, w_ptr, h_ptr) *w_ptr += cx - (*x_ptr + *w_ptr); } +/* + * 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 + * that case new color will be stored in *colorPtr. + */ + static Bool CheckSolidTile(rfbClientPtr cl, int x, int y, int w, int h, uint32_t* colorPtr, Bool needSameColor) { switch(cl->screen->rfbServerFormat.bitsPerPixel) { diff --git a/vncauth.c b/vncauth.c index f701b84..39ba856 100644 --- a/vncauth.c +++ b/vncauth.c @@ -142,9 +142,13 @@ void vncRandomBytes(unsigned char *bytes) { int i; - unsigned int seed = (unsigned int) time(0); + static Bool s_srandom_called = FALSE; + + if (!s_srandom_called) { + srandom((unsigned int)time(0) ^ (unsigned int)getpid()); + s_srandom_called = TRUE; + } - srandom(seed); for (i = 0; i < CHALLENGESIZE; i++) { bytes[i] = (unsigned char)(random() & 255); }