1 /*
2 * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved.
3 * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
4 * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
5 *
6 * This is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This software is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this software; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
20 */
21
22 /*
23 * rfbproto.c - functions to deal with client side of RFB protocol.
24 */
25
26 #ifdef __STRICT_ANSI__
27 #define _BSD_SOURCE
28 #define _POSIX_SOURCE
29 #endif
30 #ifndef WIN32
31 #include <unistd.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <pwd.h>
35 #endif
36 #include <errno.h>
37 #include <rfb/rfbclient.h>
38 #ifdef WIN32
39 #undef SOCKET
40 #undef socklen_t
41 #endif
42 #ifdef LIBVNCSERVER_HAVE_LIBZ
43 #include <zlib.h>
44 #ifdef __CHECKER__
45 #undef Z_NULL
46 #define Z_NULL NULL
47 #endif
48 #endif
49 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
50 #ifdef _RPCNDR_H /* This Windows header typedefs 'boolean', jpeglib has to know */
51 #define HAVE_BOOLEAN
52 #endif
53 #include <jpeglib.h>
54 #endif
55 #include <stdarg.h>
56 #include <time.h>
57
58 #ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT
59 #include <gcrypt.h>
60 #endif
61
62 #include "minilzo.h"
63 #include "tls.h"
64
65 /*
66 * rfbClientLog prints a time-stamped message to the log file (stderr).
67 */
68
69 rfbBool rfbEnableClientLogging=TRUE;
70
71 static void
rfbDefaultClientLog(const char * format,...)72 rfbDefaultClientLog(const char *format, ...)
73 {
74 va_list args;
75 char buf[256];
76 time_t log_clock;
77
78 if(!rfbEnableClientLogging)
79 return;
80
81 va_start(args, format);
82
83 time(&log_clock);
84 strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock));
85 fprintf(stderr, "%s", buf);
86
87 vfprintf(stderr, format, args);
88 fflush(stderr);
89
90 va_end(args);
91 }
92
93 rfbClientLogProc rfbClientLog=rfbDefaultClientLog;
94 rfbClientLogProc rfbClientErr=rfbDefaultClientLog;
95
96 /* extensions */
97
98 rfbClientProtocolExtension* rfbClientExtensions = NULL;
99
rfbClientRegisterExtension(rfbClientProtocolExtension * e)100 void rfbClientRegisterExtension(rfbClientProtocolExtension* e)
101 {
102 e->next = rfbClientExtensions;
103 rfbClientExtensions = e;
104 }
105
106 /* client data */
107
rfbClientSetClientData(rfbClient * client,void * tag,void * data)108 void rfbClientSetClientData(rfbClient* client, void* tag, void* data)
109 {
110 rfbClientData* clientData = client->clientData;
111
112 while(clientData && clientData->tag != tag)
113 clientData = clientData->next;
114 if(clientData == NULL) {
115 clientData = calloc(sizeof(rfbClientData), 1);
116 clientData->next = client->clientData;
117 client->clientData = clientData;
118 clientData->tag = tag;
119 }
120
121 clientData->data = data;
122 }
123
rfbClientGetClientData(rfbClient * client,void * tag)124 void* rfbClientGetClientData(rfbClient* client, void* tag)
125 {
126 rfbClientData* clientData = client->clientData;
127
128 while(clientData) {
129 if(clientData->tag == tag)
130 return clientData->data;
131 clientData = clientData->next;
132 }
133
134 return NULL;
135 }
136
137 /* messages */
138
FillRectangle(rfbClient * client,int x,int y,int w,int h,uint32_t colour)139 static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) {
140 int i,j;
141
142 #define FILL_RECT(BPP) \
143 for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \
144 for(i=x;i<x+w;i++) \
145 ((uint##BPP##_t*)client->frameBuffer)[j+i]=colour;
146
147 switch(client->format.bitsPerPixel) {
148 case 8: FILL_RECT(8); break;
149 case 16: FILL_RECT(16); break;
150 case 32: FILL_RECT(32); break;
151 default:
152 rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
153 }
154 }
155
CopyRectangle(rfbClient * client,uint8_t * buffer,int x,int y,int w,int h)156 static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int w, int h) {
157 int j;
158
159 #define COPY_RECT(BPP) \
160 { \
161 int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \
162 for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \
163 memcpy(client->frameBuffer + j, buffer, rs); \
164 buffer += rs; \
165 } \
166 }
167
168 switch(client->format.bitsPerPixel) {
169 case 8: COPY_RECT(8); break;
170 case 16: COPY_RECT(16); break;
171 case 32: COPY_RECT(32); break;
172 default:
173 rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
174 }
175 }
176
177 /* TODO: test */
CopyRectangleFromRectangle(rfbClient * client,int src_x,int src_y,int w,int h,int dest_x,int dest_y)178 static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) {
179 int i,j;
180
181 #define COPY_RECT_FROM_RECT(BPP) \
182 { \
183 uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \
184 if (dest_y < src_y) { \
185 for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \
186 if (dest_x < src_x) { \
187 for(i = dest_x; i < dest_x+w; i++) { \
188 ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
189 } \
190 } else { \
191 for(i = dest_x+w-1; i >= dest_x; i--) { \
192 ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
193 } \
194 } \
195 } \
196 } else { \
197 for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \
198 if (dest_x < src_x) { \
199 for(i = dest_x; i < dest_x+w; i++) { \
200 ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
201 } \
202 } else { \
203 for(i = dest_x+w-1; i >= dest_x; i--) { \
204 ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \
205 } \
206 } \
207 } \
208 } \
209 }
210
211 switch(client->format.bitsPerPixel) {
212 case 8: COPY_RECT_FROM_RECT(8); break;
213 case 16: COPY_RECT_FROM_RECT(16); break;
214 case 32: COPY_RECT_FROM_RECT(32); break;
215 default:
216 rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel);
217 }
218 }
219
220 static rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
221 static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
222 static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
223 static rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh);
224 static rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh);
225 static rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh);
226 static rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh);
227 static rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh);
228 static rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh);
229 static rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh);
230 static rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh);
231 static rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh);
232 static rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh);
233 static rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh);
234 static rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh);
235 #ifdef LIBVNCSERVER_HAVE_LIBZ
236 static rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh);
237 static rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh);
238 static rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh);
239 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
240 static rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh);
241 static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh);
242 static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh);
243
244 static long ReadCompactLen (rfbClient* client);
245
246 static void JpegInitSource(j_decompress_ptr cinfo);
247 static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
248 static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
249 static void JpegTermSource(j_decompress_ptr cinfo);
250 static void JpegSetSrcManager(j_decompress_ptr cinfo, uint8_t *compressedData,
251 int compressedLen);
252 #endif
253 static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh);
254 static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh);
255 static rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh);
256 static rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh);
257 static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh);
258 static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh);
259 static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh);
260 #endif
261
262 /*
263 * Server Capability Functions
264 */
265 rfbBool
SupportsClient2Server(rfbClient * client,int messageType)266 SupportsClient2Server(rfbClient* client, int messageType)
267 {
268 return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
269 }
270
271 rfbBool
SupportsServer2Client(rfbClient * client,int messageType)272 SupportsServer2Client(rfbClient* client, int messageType)
273 {
274 return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE);
275 }
276
277 void
SetClient2Server(rfbClient * client,int messageType)278 SetClient2Server(rfbClient* client, int messageType)
279 {
280 client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
281 }
282
283 void
SetServer2Client(rfbClient * client,int messageType)284 SetServer2Client(rfbClient* client, int messageType)
285 {
286 client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8));
287 }
288
289 void
ClearClient2Server(rfbClient * client,int messageType)290 ClearClient2Server(rfbClient* client, int messageType)
291 {
292 client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
293 }
294
295 void
ClearServer2Client(rfbClient * client,int messageType)296 ClearServer2Client(rfbClient* client, int messageType)
297 {
298 client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8)));
299 }
300
301
302 void
DefaultSupportedMessages(rfbClient * client)303 DefaultSupportedMessages(rfbClient* client)
304 {
305 memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages));
306
307 /* Default client supported messages (universal RFB 3.3 protocol) */
308 SetClient2Server(client, rfbSetPixelFormat);
309 /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */
310 SetClient2Server(client, rfbSetEncodings);
311 SetClient2Server(client, rfbFramebufferUpdateRequest);
312 SetClient2Server(client, rfbKeyEvent);
313 SetClient2Server(client, rfbPointerEvent);
314 SetClient2Server(client, rfbClientCutText);
315 /* technically, we only care what we can *send* to the server
316 * but, we set Server2Client Just in case it ever becomes useful
317 */
318 SetServer2Client(client, rfbFramebufferUpdate);
319 SetServer2Client(client, rfbSetColourMapEntries);
320 SetServer2Client(client, rfbBell);
321 SetServer2Client(client, rfbServerCutText);
322 }
323
324 void
DefaultSupportedMessagesUltraVNC(rfbClient * client)325 DefaultSupportedMessagesUltraVNC(rfbClient* client)
326 {
327 DefaultSupportedMessages(client);
328 SetClient2Server(client, rfbFileTransfer);
329 SetClient2Server(client, rfbSetScale);
330 SetClient2Server(client, rfbSetServerInput);
331 SetClient2Server(client, rfbSetSW);
332 SetClient2Server(client, rfbTextChat);
333 SetClient2Server(client, rfbPalmVNCSetScaleFactor);
334 /* technically, we only care what we can *send* to the server */
335 SetServer2Client(client, rfbResizeFrameBuffer);
336 SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer);
337 SetServer2Client(client, rfbFileTransfer);
338 SetServer2Client(client, rfbTextChat);
339 }
340
341
342 void
DefaultSupportedMessagesTightVNC(rfbClient * client)343 DefaultSupportedMessagesTightVNC(rfbClient* client)
344 {
345 DefaultSupportedMessages(client);
346 SetClient2Server(client, rfbFileTransfer);
347 SetClient2Server(client, rfbSetServerInput);
348 SetClient2Server(client, rfbSetSW);
349 /* SetClient2Server(client, rfbTextChat); */
350 /* technically, we only care what we can *send* to the server */
351 SetServer2Client(client, rfbFileTransfer);
352 SetServer2Client(client, rfbTextChat);
353 }
354
355 #ifndef WIN32
356 static rfbBool
IsUnixSocket(const char * name)357 IsUnixSocket(const char *name)
358 {
359 struct stat sb;
360 if(stat(name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK)
361 return TRUE;
362 return FALSE;
363 }
364 #endif
365
366 /*
367 * ConnectToRFBServer.
368 */
369
370 rfbBool
ConnectToRFBServer(rfbClient * client,const char * hostname,int port)371 ConnectToRFBServer(rfbClient* client,const char *hostname, int port)
372 {
373 if (client->serverPort==-1) {
374 /* serverHost is a file recorded by vncrec. */
375 const char* magic="vncLog0.0";
376 char buffer[10];
377 rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec));
378 client->vncRec = rec;
379
380 rec->file = fopen(client->serverHost,"rb");
381 rec->tv.tv_sec = 0;
382 rec->readTimestamp = FALSE;
383 rec->doNotSleep = FALSE;
384
385 if (!rec->file) {
386 rfbClientLog("Could not open %s.\n",client->serverHost);
387 return FALSE;
388 }
389 setbuf(rec->file,NULL);
390 fread(buffer,1,strlen(magic),rec->file);
391 if (strncmp(buffer,magic,strlen(magic))) {
392 rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost);
393 fclose(rec->file);
394 return FALSE;
395 }
396 client->sock = -1;
397 return TRUE;
398 }
399
400 #ifndef WIN32
401 if(IsUnixSocket(hostname))
402 /* serverHost is a UNIX socket. */
403 client->sock = ConnectClientToUnixSock(hostname);
404 else
405 #endif
406 {
407 #ifdef LIBVNCSERVER_IPv6
408 client->sock = ConnectClientToTcpAddr6(hostname, port);
409 if (client->sock == -1)
410 #endif
411 {
412 unsigned int host;
413
414 /* serverHost is a hostname */
415 if (!StringToIPAddr(hostname, &host)) {
416 rfbClientLog("Couldn't convert '%s' to host address\n", hostname);
417 return FALSE;
418 }
419 client->sock = ConnectClientToTcpAddr(host, port);
420 }
421 }
422
423 if (client->sock < 0) {
424 rfbClientLog("Unable to connect to VNC server\n");
425 return FALSE;
426 }
427
428 if(client->QoS_DSCP && !SetDSCP(client->sock, client->QoS_DSCP))
429 return FALSE;
430
431 return SetNonBlocking(client->sock);
432 }
433
434 /*
435 * ConnectToRFBRepeater.
436 */
437
ConnectToRFBRepeater(rfbClient * client,const char * repeaterHost,int repeaterPort,const char * destHost,int destPort)438 rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort)
439 {
440 rfbProtocolVersionMsg pv;
441 int major,minor;
442 char tmphost[250];
443
444 #ifdef LIBVNCSERVER_IPv6
445 client->sock = ConnectClientToTcpAddr6(repeaterHost, repeaterPort);
446 if (client->sock == -1)
447 #endif
448 {
449 unsigned int host;
450 if (!StringToIPAddr(repeaterHost, &host)) {
451 rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost);
452 return FALSE;
453 }
454
455 client->sock = ConnectClientToTcpAddr(host, repeaterPort);
456 }
457
458 if (client->sock < 0) {
459 rfbClientLog("Unable to connect to VNC repeater\n");
460 return FALSE;
461 }
462
463 if (!SetNonBlocking(client->sock))
464 return FALSE;
465
466 if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg))
467 return FALSE;
468 pv[sz_rfbProtocolVersionMsg] = 0;
469
470 /* UltraVNC repeater always report version 000.000 to identify itself */
471 if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) {
472 rfbClientLog("Not a valid VNC repeater (%s)\n",pv);
473 return FALSE;
474 }
475
476 rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor);
477
478 snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort);
479 if (!WriteToRFBServer(client, tmphost, sizeof(tmphost)))
480 return FALSE;
481
482 return TRUE;
483 }
484
485 extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd);
486 extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key);
487
488 rfbBool
rfbHandleAuthResult(rfbClient * client)489 rfbHandleAuthResult(rfbClient* client)
490 {
491 uint32_t authResult=0, reasonLen=0;
492 char *reason=NULL;
493
494 if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE;
495
496 authResult = rfbClientSwap32IfLE(authResult);
497
498 switch (authResult) {
499 case rfbVncAuthOK:
500 rfbClientLog("VNC authentication succeeded\n");
501 return TRUE;
502 break;
503 case rfbVncAuthFailed:
504 if (client->major==3 && client->minor>7)
505 {
506 /* we have an error following */
507 if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return FALSE;
508 reasonLen = rfbClientSwap32IfLE(reasonLen);
509 reason = malloc(reasonLen+1);
510 if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return FALSE; }
511 reason[reasonLen]=0;
512 rfbClientLog("VNC connection failed: %s\n",reason);
513 free(reason);
514 return FALSE;
515 }
516 rfbClientLog("VNC authentication failed\n");
517 return FALSE;
518 case rfbVncAuthTooMany:
519 rfbClientLog("VNC authentication failed - too many tries\n");
520 return FALSE;
521 }
522
523 rfbClientLog("Unknown VNC authentication result: %d\n",
524 (int)authResult);
525 return FALSE;
526 }
527
528 static void
ReadReason(rfbClient * client)529 ReadReason(rfbClient* client)
530 {
531 uint32_t reasonLen;
532 char *reason;
533
534 /* we have an error following */
535 if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return;
536 reasonLen = rfbClientSwap32IfLE(reasonLen);
537 reason = malloc(reasonLen+1);
538 if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; }
539 reason[reasonLen]=0;
540 rfbClientLog("VNC connection failed: %s\n",reason);
541 free(reason);
542 }
543
544 static rfbBool
ReadSupportedSecurityType(rfbClient * client,uint32_t * result,rfbBool subAuth)545 ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth)
546 {
547 uint8_t count=0;
548 uint8_t loop=0;
549 uint8_t flag=0;
550 uint8_t tAuth[256];
551 char buf1[500],buf2[10];
552 uint32_t authScheme;
553
554 if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
555
556 if (count==0)
557 {
558 rfbClientLog("List of security types is ZERO, expecting an error to follow\n");
559 ReadReason(client);
560 return FALSE;
561 }
562
563 rfbClientLog("We have %d security types to read\n", count);
564 authScheme=0;
565 /* now, we have a list of available security types to read ( uint8_t[] ) */
566 for (loop=0;loop<count;loop++)
567 {
568 if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
569 rfbClientLog("%d) Received security type %d\n", loop, tAuth[loop]);
570 if (flag) continue;
571 if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth ||
572 (tAuth[loop]==rfbARD && client->GetCredential) ||
573 (!subAuth && (tAuth[loop]==rfbTLS || (tAuth[loop]==rfbVeNCrypt && client->GetCredential))))
574 {
575 if (!subAuth && client->clientAuthSchemes)
576 {
577 int i;
578 for (i=0;client->clientAuthSchemes[i];i++)
579 {
580 if (client->clientAuthSchemes[i]==(uint32_t)tAuth[loop])
581 {
582 flag++;
583 authScheme=tAuth[loop];
584 break;
585 }
586 }
587 }
588 else
589 {
590 flag++;
591 authScheme=tAuth[loop];
592 }
593 if (flag)
594 {
595 rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
596 /* send back a single byte indicating which security type to use */
597 if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE;
598 }
599 }
600 }
601 if (authScheme==0)
602 {
603 memset(buf1, 0, sizeof(buf1));
604 for (loop=0;loop<count;loop++)
605 {
606 if (strlen(buf1)>=sizeof(buf1)-1) break;
607 snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
608 strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
609 }
610 rfbClientLog("Unknown authentication scheme from VNC server: %s\n",
611 buf1);
612 return FALSE;
613 }
614 *result = authScheme;
615 return TRUE;
616 }
617
618 static rfbBool
HandleVncAuth(rfbClient * client)619 HandleVncAuth(rfbClient *client)
620 {
621 uint8_t challenge[CHALLENGESIZE];
622 char *passwd=NULL;
623 int i;
624
625 if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
626
627 if (client->serverPort!=-1) { /* if not playing a vncrec file */
628 if (client->GetPassword)
629 passwd = client->GetPassword(client);
630
631 if ((!passwd) || (strlen(passwd) == 0)) {
632 rfbClientLog("Reading password failed\n");
633 return FALSE;
634 }
635 if (strlen(passwd) > 8) {
636 passwd[8] = '\0';
637 }
638
639 rfbClientEncryptBytes(challenge, passwd);
640
641 /* Lose the password from memory */
642 for (i = strlen(passwd); i >= 0; i--) {
643 passwd[i] = '\0';
644 }
645 free(passwd);
646
647 if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE;
648 }
649
650 /* Handle the SecurityResult message */
651 if (!rfbHandleAuthResult(client)) return FALSE;
652
653 return TRUE;
654 }
655
656 static void
FreeUserCredential(rfbCredential * cred)657 FreeUserCredential(rfbCredential *cred)
658 {
659 if (cred->userCredential.username) free(cred->userCredential.username);
660 if (cred->userCredential.password) free(cred->userCredential.password);
661 free(cred);
662 }
663
664 static rfbBool
HandlePlainAuth(rfbClient * client)665 HandlePlainAuth(rfbClient *client)
666 {
667 uint32_t ulen, ulensw;
668 uint32_t plen, plensw;
669 rfbCredential *cred;
670
671 if (!client->GetCredential)
672 {
673 rfbClientLog("GetCredential callback is not set.\n");
674 return FALSE;
675 }
676 cred = client->GetCredential(client, rfbCredentialTypeUser);
677 if (!cred)
678 {
679 rfbClientLog("Reading credential failed\n");
680 return FALSE;
681 }
682
683 ulen = (cred->userCredential.username ? strlen(cred->userCredential.username) : 0);
684 ulensw = rfbClientSwap32IfLE(ulen);
685 plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0);
686 plensw = rfbClientSwap32IfLE(plen);
687 if (!WriteToRFBServer(client, (char *)&ulensw, 4) ||
688 !WriteToRFBServer(client, (char *)&plensw, 4))
689 {
690 FreeUserCredential(cred);
691 return FALSE;
692 }
693 if (ulen > 0)
694 {
695 if (!WriteToRFBServer(client, cred->userCredential.username, ulen))
696 {
697 FreeUserCredential(cred);
698 return FALSE;
699 }
700 }
701 if (plen > 0)
702 {
703 if (!WriteToRFBServer(client, cred->userCredential.password, plen))
704 {
705 FreeUserCredential(cred);
706 return FALSE;
707 }
708 }
709
710 FreeUserCredential(cred);
711
712 /* Handle the SecurityResult message */
713 if (!rfbHandleAuthResult(client)) return FALSE;
714
715 return TRUE;
716 }
717
718 /* Simple 64bit big integer arithmetic implementation */
719 /* (x + y) % m, works even if (x + y) > 64bit */
720 #define rfbAddM64(x,y,m) ((x+y)%m+(x+y<x?(((uint64_t)-1)%m+1)%m:0))
721 /* (x * y) % m */
722 static uint64_t
rfbMulM64(uint64_t x,uint64_t y,uint64_t m)723 rfbMulM64(uint64_t x, uint64_t y, uint64_t m)
724 {
725 uint64_t r;
726 for(r=0;x>0;x>>=1)
727 {
728 if (x&1) r=rfbAddM64(r,y,m);
729 y=rfbAddM64(y,y,m);
730 }
731 return r;
732 }
733 /* (x ^ y) % m */
734 static uint64_t
rfbPowM64(uint64_t b,uint64_t e,uint64_t m)735 rfbPowM64(uint64_t b, uint64_t e, uint64_t m)
736 {
737 uint64_t r;
738 for(r=1;e>0;e>>=1)
739 {
740 if(e&1) r=rfbMulM64(r,b,m);
741 b=rfbMulM64(b,b,m);
742 }
743 return r;
744 }
745
746 static rfbBool
HandleMSLogonAuth(rfbClient * client)747 HandleMSLogonAuth(rfbClient *client)
748 {
749 uint64_t gen, mod, resp, priv, pub, key;
750 uint8_t username[256], password[64];
751 rfbCredential *cred;
752
753 if (!ReadFromRFBServer(client, (char *)&gen, 8)) return FALSE;
754 if (!ReadFromRFBServer(client, (char *)&mod, 8)) return FALSE;
755 if (!ReadFromRFBServer(client, (char *)&resp, 8)) return FALSE;
756 gen = rfbClientSwap64IfLE(gen);
757 mod = rfbClientSwap64IfLE(mod);
758 resp = rfbClientSwap64IfLE(resp);
759
760 if (!client->GetCredential)
761 {
762 rfbClientLog("GetCredential callback is not set.\n");
763 return FALSE;
764 }
765 rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\
766 "Use it only with SSH tunnel or trusted network.\n");
767 cred = client->GetCredential(client, rfbCredentialTypeUser);
768 if (!cred)
769 {
770 rfbClientLog("Reading credential failed\n");
771 return FALSE;
772 }
773
774 memset(username, 0, sizeof(username));
775 strncpy((char *)username, cred->userCredential.username, sizeof(username));
776 memset(password, 0, sizeof(password));
777 strncpy((char *)password, cred->userCredential.password, sizeof(password));
778 FreeUserCredential(cred);
779
780 srand(time(NULL));
781 priv = ((uint64_t)rand())<<32;
782 priv |= (uint64_t)rand();
783
784 pub = rfbPowM64(gen, priv, mod);
785 key = rfbPowM64(resp, priv, mod);
786 pub = rfbClientSwap64IfLE(pub);
787 key = rfbClientSwap64IfLE(key);
788
789 rfbClientEncryptBytes2(username, sizeof(username), (unsigned char *)&key);
790 rfbClientEncryptBytes2(password, sizeof(password), (unsigned char *)&key);
791
792 if (!WriteToRFBServer(client, (char *)&pub, 8)) return FALSE;
793 if (!WriteToRFBServer(client, (char *)username, sizeof(username))) return FALSE;
794 if (!WriteToRFBServer(client, (char *)password, sizeof(password))) return FALSE;
795
796 /* Handle the SecurityResult message */
797 if (!rfbHandleAuthResult(client)) return FALSE;
798
799 return TRUE;
800 }
801
802 #ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT
803 static rfbBool
rfbMpiToBytes(const gcry_mpi_t value,uint8_t * result,size_t size)804 rfbMpiToBytes(const gcry_mpi_t value, uint8_t *result, size_t size)
805 {
806 gcry_error_t error;
807 size_t len;
808 int i;
809
810 error = gcry_mpi_print(GCRYMPI_FMT_USG, result, size, &len, value);
811 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
812 {
813 rfbClientLog("gcry_mpi_print error: %s\n", gcry_strerror(error));
814 return FALSE;
815 }
816 for (i=size-1;i>(int)size-1-(int)len;--i)
817 result[i] = result[i-size+len];
818 for (;i>=0;--i)
819 result[i] = 0;
820 return TRUE;
821 }
822
823 static rfbBool
HandleARDAuth(rfbClient * client)824 HandleARDAuth(rfbClient *client)
825 {
826 uint8_t gen[2], len[2];
827 size_t keylen;
828 uint8_t *mod = NULL, *resp, *pub, *key, *shared;
829 gcry_mpi_t genmpi = NULL, modmpi = NULL, respmpi = NULL;
830 gcry_mpi_t privmpi = NULL, pubmpi = NULL, keympi = NULL;
831 gcry_md_hd_t md5 = NULL;
832 gcry_cipher_hd_t aes = NULL;
833 gcry_error_t error;
834 uint8_t userpass[128], ciphertext[128];
835 int passwordLen, usernameLen;
836 rfbCredential *cred = NULL;
837 rfbBool result = FALSE;
838
839 while (1)
840 {
841 if (!ReadFromRFBServer(client, (char *)gen, 2))
842 break;
843 if (!ReadFromRFBServer(client, (char *)len, 2))
844 break;
845
846 if (!client->GetCredential)
847 {
848 rfbClientLog("GetCredential callback is not set.\n");
849 break;
850 }
851 cred = client->GetCredential(client, rfbCredentialTypeUser);
852 if (!cred)
853 {
854 rfbClientLog("Reading credential failed\n");
855 break;
856 }
857
858 keylen = 256*len[0]+len[1];
859 mod = (uint8_t*)malloc(keylen*4);
860 if (!mod)
861 {
862 rfbClientLog("malloc out of memory\n");
863 break;
864 }
865 resp = mod+keylen;
866 pub = resp+keylen;
867 key = pub+keylen;
868
869 if (!ReadFromRFBServer(client, (char *)mod, keylen))
870 break;
871 if (!ReadFromRFBServer(client, (char *)resp, keylen))
872 break;
873
874 error = gcry_mpi_scan(&genmpi, GCRYMPI_FMT_USG, gen, 2, NULL);
875 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
876 {
877 rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
878 break;
879 }
880 error = gcry_mpi_scan(&modmpi, GCRYMPI_FMT_USG, mod, keylen, NULL);
881 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
882 {
883 rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
884 break;
885 }
886 error = gcry_mpi_scan(&respmpi, GCRYMPI_FMT_USG, resp, keylen, NULL);
887 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
888 {
889 rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error));
890 break;
891 }
892
893 privmpi = gcry_mpi_new(keylen);
894 if (!privmpi)
895 {
896 rfbClientLog("gcry_mpi_new out of memory\n");
897 break;
898 }
899 gcry_mpi_randomize(privmpi, (keylen/8)*8, GCRY_STRONG_RANDOM);
900
901 pubmpi = gcry_mpi_new(keylen);
902 if (!pubmpi)
903 {
904 rfbClientLog("gcry_mpi_new out of memory\n");
905 break;
906 }
907 gcry_mpi_powm(pubmpi, genmpi, privmpi, modmpi);
908
909 keympi = gcry_mpi_new(keylen);
910 if (!keympi)
911 {
912 rfbClientLog("gcry_mpi_new out of memory\n");
913 break;
914 }
915 gcry_mpi_powm(keympi, respmpi, privmpi, modmpi);
916
917 if (!rfbMpiToBytes(pubmpi, pub, keylen))
918 break;
919 if (!rfbMpiToBytes(keympi, key, keylen))
920 break;
921
922 error = gcry_md_open(&md5, GCRY_MD_MD5, 0);
923 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
924 {
925 rfbClientLog("gcry_md_open error: %s\n", gcry_strerror(error));
926 break;
927 }
928 gcry_md_write(md5, key, keylen);
929 error = gcry_md_final(md5);
930 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
931 {
932 rfbClientLog("gcry_md_final error: %s\n", gcry_strerror(error));
933 break;
934 }
935 shared = gcry_md_read(md5, GCRY_MD_MD5);
936
937 passwordLen = strlen(cred->userCredential.password)+1;
938 usernameLen = strlen(cred->userCredential.username)+1;
939 if (passwordLen > sizeof(userpass)/2)
940 passwordLen = sizeof(userpass)/2;
941 if (usernameLen > sizeof(userpass)/2)
942 usernameLen = sizeof(userpass)/2;
943
944 gcry_randomize(userpass, sizeof(userpass), GCRY_STRONG_RANDOM);
945 memcpy(userpass, cred->userCredential.username, usernameLen);
946 memcpy(userpass+sizeof(userpass)/2, cred->userCredential.password, passwordLen);
947
948 error = gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0);
949 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
950 {
951 rfbClientLog("gcry_cipher_open error: %s\n", gcry_strerror(error));
952 break;
953 }
954 error = gcry_cipher_setkey(aes, shared, 16);
955 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
956 {
957 rfbClientLog("gcry_cipher_setkey error: %s\n", gcry_strerror(error));
958 break;
959 }
960 error = gcry_cipher_encrypt(aes, ciphertext, sizeof(ciphertext), userpass, sizeof(userpass));
961 if (gcry_err_code(error) != GPG_ERR_NO_ERROR)
962 {
963 rfbClientLog("gcry_cipher_encrypt error: %s\n", gcry_strerror(error));
964 break;
965 }
966
967 if (!WriteToRFBServer(client, (char *)ciphertext, sizeof(ciphertext)))
968 break;
969 if (!WriteToRFBServer(client, (char *)pub, keylen))
970 break;
971
972 /* Handle the SecurityResult message */
973 if (!rfbHandleAuthResult(client))
974 break;
975
976 result = TRUE;
977 break;
978 }
979
980 if (cred)
981 FreeUserCredential(cred);
982 if (mod)
983 free(mod);
984 if (genmpi)
985 gcry_mpi_release(genmpi);
986 if (modmpi)
987 gcry_mpi_release(modmpi);
988 if (respmpi)
989 gcry_mpi_release(respmpi);
990 if (privmpi)
991 gcry_mpi_release(privmpi);
992 if (pubmpi)
993 gcry_mpi_release(pubmpi);
994 if (keympi)
995 gcry_mpi_release(keympi);
996 if (md5)
997 gcry_md_close(md5);
998 if (aes)
999 gcry_cipher_close(aes);
1000 return result;
1001 }
1002 #endif
1003
1004 /*
1005 * SetClientAuthSchemes.
1006 */
1007
1008 void
SetClientAuthSchemes(rfbClient * client,const uint32_t * authSchemes,int size)1009 SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size)
1010 {
1011 int i;
1012
1013 if (client->clientAuthSchemes)
1014 {
1015 free(client->clientAuthSchemes);
1016 client->clientAuthSchemes = NULL;
1017 }
1018 if (authSchemes)
1019 {
1020 if (size<0)
1021 {
1022 /* If size<0 we assume the passed-in list is also 0-terminate, so we
1023 * calculate the size here */
1024 for (size=0;authSchemes[size];size++) ;
1025 }
1026 client->clientAuthSchemes = (uint32_t*)malloc(sizeof(uint32_t)*(size+1));
1027 for (i=0;i<size;i++)
1028 client->clientAuthSchemes[i] = authSchemes[i];
1029 client->clientAuthSchemes[size] = 0;
1030 }
1031 }
1032
1033 /*
1034 * InitialiseRFBConnection.
1035 */
1036
1037 rfbBool
InitialiseRFBConnection(rfbClient * client)1038 InitialiseRFBConnection(rfbClient* client)
1039 {
1040 rfbProtocolVersionMsg pv;
1041 int major,minor;
1042 uint32_t authScheme;
1043 uint32_t subAuthScheme;
1044 rfbClientInitMsg ci;
1045
1046 /* if the connection is immediately closed, don't report anything, so
1047 that pmw's monitor can make test connections */
1048
1049 if (client->listenSpecified)
1050 errorMessageOnReadFailure = FALSE;
1051
1052 if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
1053 pv[sz_rfbProtocolVersionMsg]=0;
1054
1055 errorMessageOnReadFailure = TRUE;
1056
1057 pv[sz_rfbProtocolVersionMsg] = 0;
1058
1059 if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
1060 rfbClientLog("Not a valid VNC server (%s)\n",pv);
1061 return FALSE;
1062 }
1063
1064
1065 DefaultSupportedMessages(client);
1066 client->major = major;
1067 client->minor = minor;
1068
1069 /* fall back to viewer supported version */
1070 if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion))
1071 client->minor = rfbProtocolMinorVersion;
1072
1073 /* UltraVNC uses minor codes 4 and 6 for the server */
1074 if (major==3 && (minor==4 || minor==6)) {
1075 rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv);
1076 DefaultSupportedMessagesUltraVNC(client);
1077 }
1078
1079 /* UltraVNC Single Click uses minor codes 14 and 16 for the server */
1080 if (major==3 && (minor==14 || minor==16)) {
1081 minor = minor - 10;
1082 client->minor = minor;
1083 rfbClientLog("UltraVNC Single Click server detected, enabling UltraVNC specific messages\n",pv);
1084 DefaultSupportedMessagesUltraVNC(client);
1085 }
1086
1087 /* TightVNC uses minor codes 5 for the server */
1088 if (major==3 && minor==5) {
1089 rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv);
1090 DefaultSupportedMessagesTightVNC(client);
1091 }
1092
1093 /* we do not support > RFB3.8 */
1094 if ((major==3 && minor>8) || major>3)
1095 {
1096 client->major=3;
1097 client->minor=8;
1098 }
1099
1100 rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n",
1101 major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
1102
1103 sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor);
1104
1105 if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE;
1106
1107
1108 /* 3.7 and onwards sends a # of security types first */
1109 if (client->major==3 && client->minor > 6)
1110 {
1111 if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE;
1112 }
1113 else
1114 {
1115 if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE;
1116 authScheme = rfbClientSwap32IfLE(authScheme);
1117 }
1118
1119 rfbClientLog("Selected Security Scheme %d\n", authScheme);
1120 client->authScheme = authScheme;
1121
1122 switch (authScheme) {
1123
1124 case rfbConnFailed:
1125 ReadReason(client);
1126 return FALSE;
1127
1128 case rfbNoAuth:
1129 rfbClientLog("No authentication needed\n");
1130
1131 /* 3.8 and upwards sends a Security Result for rfbNoAuth */
1132 if ((client->major==3 && client->minor > 7) || client->major>3)
1133 if (!rfbHandleAuthResult(client)) return FALSE;
1134
1135 break;
1136
1137 case rfbVncAuth:
1138 if (!HandleVncAuth(client)) return FALSE;
1139 break;
1140
1141 case rfbMSLogon:
1142 if (!HandleMSLogonAuth(client)) return FALSE;
1143 break;
1144
1145 case rfbARD:
1146 #ifndef LIBVNCSERVER_WITH_CLIENT_GCRYPT
1147 rfbClientLog("GCrypt support was not compiled in\n");
1148 return FALSE;
1149 #else
1150 if (!HandleARDAuth(client)) return FALSE;
1151 #endif
1152 break;
1153
1154 case rfbTLS:
1155 if (!HandleAnonTLSAuth(client)) return FALSE;
1156 /* After the TLS session is established, sub auth types are expected.
1157 * Note that all following reading/writing are through the TLS session from here.
1158 */
1159 if (!ReadSupportedSecurityType(client, &subAuthScheme, TRUE)) return FALSE;
1160 client->subAuthScheme = subAuthScheme;
1161
1162 switch (subAuthScheme) {
1163
1164 case rfbConnFailed:
1165 ReadReason(client);
1166 return FALSE;
1167
1168 case rfbNoAuth:
1169 rfbClientLog("No sub authentication needed\n");
1170 /* 3.8 and upwards sends a Security Result for rfbNoAuth */
1171 if ((client->major==3 && client->minor > 7) || client->major>3)
1172 if (!rfbHandleAuthResult(client)) return FALSE;
1173 break;
1174
1175 case rfbVncAuth:
1176 if (!HandleVncAuth(client)) return FALSE;
1177 break;
1178
1179 default:
1180 rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
1181 (int)subAuthScheme);
1182 return FALSE;
1183 }
1184
1185 break;
1186
1187 case rfbVeNCrypt:
1188 if (!HandleVeNCryptAuth(client)) return FALSE;
1189
1190 switch (client->subAuthScheme) {
1191
1192 case rfbVeNCryptTLSNone:
1193 case rfbVeNCryptX509None:
1194 rfbClientLog("No sub authentication needed\n");
1195 if (!rfbHandleAuthResult(client)) return FALSE;
1196 break;
1197
1198 case rfbVeNCryptTLSVNC:
1199 case rfbVeNCryptX509VNC:
1200 if (!HandleVncAuth(client)) return FALSE;
1201 break;
1202
1203 case rfbVeNCryptTLSPlain:
1204 case rfbVeNCryptX509Plain:
1205 if (!HandlePlainAuth(client)) return FALSE;
1206 break;
1207
1208 default:
1209 rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n",
1210 client->subAuthScheme);
1211 return FALSE;
1212 }
1213
1214 break;
1215
1216 default:
1217 rfbClientLog("Unknown authentication scheme from VNC server: %d\n",
1218 (int)authScheme);
1219 return FALSE;
1220 }
1221
1222 ci.shared = (client->appData.shareDesktop ? 1 : 0);
1223
1224 if (!WriteToRFBServer(client, (char *)&ci, sz_rfbClientInitMsg)) return FALSE;
1225
1226 if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE;
1227
1228 client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth);
1229 client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight);
1230 client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax);
1231 client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax);
1232 client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax);
1233 client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength);
1234
1235 client->desktopName = malloc(client->si.nameLength + 1);
1236 if (!client->desktopName) {
1237 rfbClientLog("Error allocating memory for desktop name, %lu bytes\n",
1238 (unsigned long)client->si.nameLength);
1239 return FALSE;
1240 }
1241
1242 if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE;
1243
1244 client->desktopName[client->si.nameLength] = 0;
1245
1246 rfbClientLog("Desktop name \"%s\"\n",client->desktopName);
1247
1248 rfbClientLog("Connected to VNC server, using protocol version %d.%d\n",
1249 client->major, client->minor);
1250
1251 rfbClientLog("VNC server default format:\n");
1252 PrintPixelFormat(&client->si.format);
1253
1254 return TRUE;
1255 }
1256
1257
1258 /*
1259 * SetFormatAndEncodings.
1260 */
1261
1262 rfbBool
SetFormatAndEncodings(rfbClient * client)1263 SetFormatAndEncodings(rfbClient* client)
1264 {
1265 rfbSetPixelFormatMsg spf;
1266 char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
1267
1268 rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
1269 uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]);
1270 int len = 0;
1271 rfbBool requestCompressLevel = FALSE;
1272 rfbBool requestQualityLevel = FALSE;
1273 rfbBool requestLastRectEncoding = FALSE;
1274 rfbClientProtocolExtension* e;
1275
1276 if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE;
1277
1278 spf.type = rfbSetPixelFormat;
1279 spf.format = client->format;
1280 spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax);
1281 spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax);
1282 spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax);
1283
1284 if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg))
1285 return FALSE;
1286
1287
1288 if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE;
1289
1290 se->type = rfbSetEncodings;
1291 se->nEncodings = 0;
1292
1293 if (client->appData.encodingsString) {
1294 const char *encStr = client->appData.encodingsString;
1295 int encStrLen;
1296 do {
1297 const char *nextEncStr = strchr(encStr, ' ');
1298 if (nextEncStr) {
1299 encStrLen = nextEncStr - encStr;
1300 nextEncStr++;
1301 } else {
1302 encStrLen = strlen(encStr);
1303 }
1304
1305 if (strncasecmp(encStr,"raw",encStrLen) == 0) {
1306 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
1307 } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
1308 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
1309 #ifdef LIBVNCSERVER_HAVE_LIBZ
1310 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
1311 } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
1312 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
1313 requestLastRectEncoding = TRUE;
1314 if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
1315 requestCompressLevel = TRUE;
1316 if (client->appData.enableJPEG)
1317 requestQualityLevel = TRUE;
1318 #endif
1319 #endif
1320 } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
1321 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
1322 #ifdef LIBVNCSERVER_HAVE_LIBZ
1323 } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
1324 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
1325 if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
1326 requestCompressLevel = TRUE;
1327 } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) {
1328 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex);
1329 if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9)
1330 requestCompressLevel = TRUE;
1331 } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) {
1332 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
1333 } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) {
1334 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
1335 requestQualityLevel = TRUE;
1336 #endif
1337 } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) {
1338 /* There are 2 encodings used in 'ultra' */
1339 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
1340 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
1341 } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
1342 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
1343 } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
1344 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
1345 } else {
1346 rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr);
1347 }
1348
1349 encStr = nextEncStr;
1350 } while (encStr && se->nEncodings < MAX_ENCODINGS);
1351
1352 if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
1353 encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
1354 rfbEncodingCompressLevel0);
1355 }
1356
1357 if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
1358 if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
1359 client->appData.qualityLevel = 5;
1360 encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
1361 rfbEncodingQualityLevel0);
1362 }
1363 }
1364 else {
1365 if (SameMachine(client->sock)) {
1366 /* TODO:
1367 if (!tunnelSpecified) {
1368 */
1369 rfbClientLog("Same machine: preferring raw encoding\n");
1370 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw);
1371 /*
1372 } else {
1373 rfbClientLog("Tunneling active: preferring tight encoding\n");
1374 }
1375 */
1376 }
1377
1378 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect);
1379 #ifdef LIBVNCSERVER_HAVE_LIBZ
1380 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
1381 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight);
1382 requestLastRectEncoding = TRUE;
1383 #endif
1384 #endif
1385 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile);
1386 #ifdef LIBVNCSERVER_HAVE_LIBZ
1387 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib);
1388 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE);
1389 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE);
1390 #endif
1391 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra);
1392 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip);
1393 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE);
1394 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE);
1395
1396 if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) {
1397 encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel +
1398 rfbEncodingCompressLevel0);
1399 } else /* if (!tunnelSpecified) */ {
1400 /* If -tunnel option was provided, we assume that server machine is
1401 not in the local network so we use default compression level for
1402 tight encoding instead of fast compression. Thus we are
1403 requesting level 1 compression only if tunneling is not used. */
1404 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1);
1405 }
1406
1407 if (client->appData.enableJPEG) {
1408 if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9)
1409 client->appData.qualityLevel = 5;
1410 encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel +
1411 rfbEncodingQualityLevel0);
1412 }
1413 }
1414
1415
1416
1417 /* Remote Cursor Support (local to viewer) */
1418 if (client->appData.useRemoteCursor) {
1419 if (se->nEncodings < MAX_ENCODINGS)
1420 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor);
1421 if (se->nEncodings < MAX_ENCODINGS)
1422 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor);
1423 if (se->nEncodings < MAX_ENCODINGS)
1424 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos);
1425 }
1426
1427 /* Keyboard State Encodings */
1428 if (se->nEncodings < MAX_ENCODINGS)
1429 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState);
1430
1431 /* New Frame Buffer Size */
1432 if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize)
1433 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize);
1434
1435 /* Last Rect */
1436 if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding)
1437 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect);
1438
1439 /* Server Capabilities */
1440 if (se->nEncodings < MAX_ENCODINGS)
1441 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages);
1442 if (se->nEncodings < MAX_ENCODINGS)
1443 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings);
1444 if (se->nEncodings < MAX_ENCODINGS)
1445 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity);
1446
1447 /* xvp */
1448 if (se->nEncodings < MAX_ENCODINGS)
1449 encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXvp);
1450
1451 /* client extensions */
1452 for(e = rfbClientExtensions; e; e = e->next)
1453 if(e->encodings) {
1454 int* enc;
1455 for(enc = e->encodings; *enc; enc++)
1456 encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc);
1457 }
1458
1459 len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
1460
1461 se->nEncodings = rfbClientSwap16IfLE(se->nEncodings);
1462
1463 if (!WriteToRFBServer(client, buf, len)) return FALSE;
1464
1465 return TRUE;
1466 }
1467
1468
1469 /*
1470 * SendIncrementalFramebufferUpdateRequest.
1471 */
1472
1473 rfbBool
SendIncrementalFramebufferUpdateRequest(rfbClient * client)1474 SendIncrementalFramebufferUpdateRequest(rfbClient* client)
1475 {
1476 return SendFramebufferUpdateRequest(client,
1477 client->updateRect.x, client->updateRect.y,
1478 client->updateRect.w, client->updateRect.h, TRUE);
1479 }
1480
1481
1482 /*
1483 * SendFramebufferUpdateRequest.
1484 */
1485
1486 rfbBool
SendFramebufferUpdateRequest(rfbClient * client,int x,int y,int w,int h,rfbBool incremental)1487 SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental)
1488 {
1489 rfbFramebufferUpdateRequestMsg fur;
1490
1491 if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE;
1492
1493 fur.type = rfbFramebufferUpdateRequest;
1494 fur.incremental = incremental ? 1 : 0;
1495 fur.x = rfbClientSwap16IfLE(x);
1496 fur.y = rfbClientSwap16IfLE(y);
1497 fur.w = rfbClientSwap16IfLE(w);
1498 fur.h = rfbClientSwap16IfLE(h);
1499
1500 if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
1501 return FALSE;
1502
1503 return TRUE;
1504 }
1505
1506
1507 /*
1508 * SendScaleSetting.
1509 */
1510 rfbBool
SendScaleSetting(rfbClient * client,int scaleSetting)1511 SendScaleSetting(rfbClient* client,int scaleSetting)
1512 {
1513 rfbSetScaleMsg ssm;
1514
1515 ssm.scale = scaleSetting;
1516 ssm.pad = 0;
1517
1518 /* favor UltraVNC SetScale if both are supported */
1519 if (SupportsClient2Server(client, rfbSetScale)) {
1520 ssm.type = rfbSetScale;
1521 if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
1522 return FALSE;
1523 }
1524
1525 if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) {
1526 ssm.type = rfbPalmVNCSetScaleFactor;
1527 if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg))
1528 return FALSE;
1529 }
1530
1531 return TRUE;
1532 }
1533
1534 /*
1535 * TextChatFunctions (UltraVNC)
1536 * Extremely bandwidth friendly method of communicating with a user
1537 * (Think HelpDesk type applications)
1538 */
1539
TextChatSend(rfbClient * client,char * text)1540 rfbBool TextChatSend(rfbClient* client, char *text)
1541 {
1542 rfbTextChatMsg chat;
1543 int count = strlen(text);
1544
1545 if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1546 chat.type = rfbTextChat;
1547 chat.pad1 = 0;
1548 chat.pad2 = 0;
1549 chat.length = (uint32_t)count;
1550 chat.length = rfbClientSwap32IfLE(chat.length);
1551
1552 if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg))
1553 return FALSE;
1554
1555 if (count>0) {
1556 if (!WriteToRFBServer(client, text, count))
1557 return FALSE;
1558 }
1559 return TRUE;
1560 }
1561
TextChatOpen(rfbClient * client)1562 rfbBool TextChatOpen(rfbClient* client)
1563 {
1564 rfbTextChatMsg chat;
1565
1566 if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1567 chat.type = rfbTextChat;
1568 chat.pad1 = 0;
1569 chat.pad2 = 0;
1570 chat.length = rfbClientSwap32IfLE(rfbTextChatOpen);
1571 return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
1572 }
1573
TextChatClose(rfbClient * client)1574 rfbBool TextChatClose(rfbClient* client)
1575 {
1576 rfbTextChatMsg chat;
1577 if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1578 chat.type = rfbTextChat;
1579 chat.pad1 = 0;
1580 chat.pad2 = 0;
1581 chat.length = rfbClientSwap32IfLE(rfbTextChatClose);
1582 return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
1583 }
1584
TextChatFinish(rfbClient * client)1585 rfbBool TextChatFinish(rfbClient* client)
1586 {
1587 rfbTextChatMsg chat;
1588 if (!SupportsClient2Server(client, rfbTextChat)) return TRUE;
1589 chat.type = rfbTextChat;
1590 chat.pad1 = 0;
1591 chat.pad2 = 0;
1592 chat.length = rfbClientSwap32IfLE(rfbTextChatFinished);
1593 return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE);
1594 }
1595
1596 /*
1597 * UltraVNC Server Input Disable
1598 * Apparently, the remote client can *prevent* the local user from interacting with the display
1599 * I would think this is extremely helpful when used in a HelpDesk situation
1600 */
PermitServerInput(rfbClient * client,int enabled)1601 rfbBool PermitServerInput(rfbClient* client, int enabled)
1602 {
1603 rfbSetServerInputMsg msg;
1604
1605 if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE;
1606 /* enabled==1, then server input from local keyboard is disabled */
1607 msg.type = rfbSetServerInput;
1608 msg.status = (enabled ? 1 : 0);
1609 msg.pad = 0;
1610 return (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE);
1611 }
1612
1613
1614 /*
1615 * send xvp client message
1616 * A client supporting the xvp extension sends this to request that the server initiate
1617 * a clean shutdown, clean reboot or abrupt reset of the system whose framebuffer the
1618 * client is displaying.
1619 *
1620 * only version 1 is defined in the protocol specs
1621 *
1622 * possible values for code are:
1623 * rfbXvp_Shutdown
1624 * rfbXvp_Reboot
1625 * rfbXvp_Reset
1626 */
1627
SendXvpMsg(rfbClient * client,uint8_t version,uint8_t code)1628 rfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code)
1629 {
1630 rfbXvpMsg xvp;
1631
1632 if (!SupportsClient2Server(client, rfbXvp)) return TRUE;
1633 xvp.type = rfbXvp;
1634 xvp.pad = 0;
1635 xvp.version = version;
1636 xvp.code = code;
1637
1638 if (!WriteToRFBServer(client, (char *)&xvp, sz_rfbXvpMsg))
1639 return FALSE;
1640
1641 return TRUE;
1642 }
1643
1644
1645 /*
1646 * SendPointerEvent.
1647 */
1648
1649 rfbBool
SendPointerEvent(rfbClient * client,int x,int y,int buttonMask)1650 SendPointerEvent(rfbClient* client,int x, int y, int buttonMask)
1651 {
1652 rfbPointerEventMsg pe;
1653
1654 if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE;
1655
1656 pe.type = rfbPointerEvent;
1657 pe.buttonMask = buttonMask;
1658 if (x < 0) x = 0;
1659 if (y < 0) y = 0;
1660
1661 pe.x = rfbClientSwap16IfLE(x);
1662 pe.y = rfbClientSwap16IfLE(y);
1663 return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg);
1664 }
1665
1666
1667 /*
1668 * SendKeyEvent.
1669 */
1670
1671 rfbBool
SendKeyEvent(rfbClient * client,uint32_t key,rfbBool down)1672 SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down)
1673 {
1674 rfbKeyEventMsg ke;
1675
1676 if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE;
1677
1678 ke.type = rfbKeyEvent;
1679 ke.down = down ? 1 : 0;
1680 ke.key = rfbClientSwap32IfLE(key);
1681 return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg);
1682 }
1683
1684
1685 /*
1686 * SendClientCutText.
1687 */
1688
1689 rfbBool
SendClientCutText(rfbClient * client,char * str,int len)1690 SendClientCutText(rfbClient* client, char *str, int len)
1691 {
1692 rfbClientCutTextMsg cct;
1693
1694 if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE;
1695
1696 cct.type = rfbClientCutText;
1697 cct.length = rfbClientSwap32IfLE(len);
1698 return (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) &&
1699 WriteToRFBServer(client, str, len));
1700 }
1701
1702
1703
1704 /*
1705 * HandleRFBServerMessage.
1706 */
1707
1708 rfbBool
HandleRFBServerMessage(rfbClient * client)1709 HandleRFBServerMessage(rfbClient* client)
1710 {
1711 rfbServerToClientMsg msg;
1712
1713 if (client->serverPort==-1)
1714 client->vncRec->readTimestamp = TRUE;
1715 if (!ReadFromRFBServer(client, (char *)&msg, 1))
1716 return FALSE;
1717
1718 switch (msg.type) {
1719
1720 case rfbSetColourMapEntries:
1721 {
1722 /* TODO:
1723 int i;
1724 uint16_t rgb[3];
1725 XColor xc;
1726
1727 if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
1728 sz_rfbSetColourMapEntriesMsg - 1))
1729 return FALSE;
1730
1731 msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour);
1732 msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours);
1733
1734 for (i = 0; i < msg.scme.nColours; i++) {
1735 if (!ReadFromRFBServer(client, (char *)rgb, 6))
1736 return FALSE;
1737 xc.pixel = msg.scme.firstColour + i;
1738 xc.red = rfbClientSwap16IfLE(rgb[0]);
1739 xc.green = rfbClientSwap16IfLE(rgb[1]);
1740 xc.blue = rfbClientSwap16IfLE(rgb[2]);
1741 xc.flags = DoRed|DoGreen|DoBlue;
1742 XStoreColor(dpy, cmap, &xc);
1743 }
1744 */
1745
1746 break;
1747 }
1748
1749 case rfbFramebufferUpdate:
1750 {
1751 rfbFramebufferUpdateRectHeader rect;
1752 int linesToRead;
1753 int bytesPerLine;
1754 int i;
1755
1756 if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1,
1757 sz_rfbFramebufferUpdateMsg - 1))
1758 return FALSE;
1759
1760 msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects);
1761
1762 for (i = 0; i < msg.fu.nRects; i++) {
1763 if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader))
1764 return FALSE;
1765
1766 rect.encoding = rfbClientSwap32IfLE(rect.encoding);
1767 if (rect.encoding == rfbEncodingLastRect)
1768 break;
1769
1770 rect.r.x = rfbClientSwap16IfLE(rect.r.x);
1771 rect.r.y = rfbClientSwap16IfLE(rect.r.y);
1772 rect.r.w = rfbClientSwap16IfLE(rect.r.w);
1773 rect.r.h = rfbClientSwap16IfLE(rect.r.h);
1774
1775
1776 if (rect.encoding == rfbEncodingXCursor ||
1777 rect.encoding == rfbEncodingRichCursor) {
1778
1779 if (!HandleCursorShape(client,
1780 rect.r.x, rect.r.y, rect.r.w, rect.r.h,
1781 rect.encoding)) {
1782 return FALSE;
1783 }
1784 continue;
1785 }
1786
1787 if (rect.encoding == rfbEncodingPointerPos) {
1788 if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) {
1789 return FALSE;
1790 }
1791 continue;
1792 }
1793
1794 if (rect.encoding == rfbEncodingKeyboardLedState) {
1795 /* OK! We have received a keyboard state message!!! */
1796 client->KeyboardLedStateEnabled = 1;
1797 if (client->HandleKeyboardLedState!=NULL)
1798 client->HandleKeyboardLedState(client, rect.r.x, 0);
1799 /* stash it for the future */
1800 client->CurrentKeyboardLedState = rect.r.x;
1801 continue;
1802 }
1803
1804 if (rect.encoding == rfbEncodingNewFBSize) {
1805 client->width = rect.r.w;
1806 client->height = rect.r.h;
1807 client->updateRect.x = client->updateRect.y = 0;
1808 client->updateRect.w = client->width;
1809 client->updateRect.h = client->height;
1810 client->MallocFrameBuffer(client);
1811 SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE);
1812 rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h);
1813 continue;
1814 }
1815
1816 /* rect.r.w=byte count */
1817 if (rect.encoding == rfbEncodingSupportedMessages) {
1818 int loop;
1819 if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages))
1820 return FALSE;
1821
1822 /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */
1823 /* currently ignored by this library */
1824
1825 rfbClientLog("client2server supported messages (bit flags)\n");
1826 for (loop=0;loop<32;loop+=8)
1827 rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1828 client->supportedMessages.client2server[loop], client->supportedMessages.client2server[loop+1],
1829 client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3],
1830 client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5],
1831 client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]);
1832
1833 rfbClientLog("server2client supported messages (bit flags)\n");
1834 for (loop=0;loop<32;loop+=8)
1835 rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop,
1836 client->supportedMessages.server2client[loop], client->supportedMessages.server2client[loop+1],
1837 client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3],
1838 client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5],
1839 client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]);
1840 continue;
1841 }
1842
1843 /* rect.r.w=byte count, rect.r.h=# of encodings */
1844 if (rect.encoding == rfbEncodingSupportedEncodings) {
1845 char *buffer;
1846 buffer = malloc(rect.r.w);
1847 if (!ReadFromRFBServer(client, buffer, rect.r.w))
1848 {
1849 free(buffer);
1850 return FALSE;
1851 }
1852
1853 /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */
1854 /* currently ignored by this library */
1855 free(buffer);
1856 continue;
1857 }
1858
1859 /* rect.r.w=byte count */
1860 if (rect.encoding == rfbEncodingServerIdentity) {
1861 char *buffer;
1862 buffer = malloc(rect.r.w+1);
1863 if (!ReadFromRFBServer(client, buffer, rect.r.w))
1864 {
1865 free(buffer);
1866 return FALSE;
1867 }
1868 buffer[rect.r.w]=0; /* null terminate, just in case */
1869 rfbClientLog("Connected to Server \"%s\"\n", buffer);
1870 free(buffer);
1871 continue;
1872 }
1873
1874 /* rfbEncodingUltraZip is a collection of subrects. x = # of subrects, and h is always 0 */
1875 if (rect.encoding != rfbEncodingUltraZip)
1876 {
1877 if ((rect.r.x + rect.r.w > client->width) ||
1878 (rect.r.y + rect.r.h > client->height))
1879 {
1880 rfbClientLog("Rect too large: %dx%d at (%d, %d)\n",
1881 rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1882 return FALSE;
1883 }
1884
1885 /* UltraVNC with scaling, will send rectangles with a zero W or H
1886 *
1887 if ((rect.encoding != rfbEncodingTight) &&
1888 (rect.r.h * rect.r.w == 0))
1889 {
1890 rfbClientLog("Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1891 continue;
1892 }
1893 */
1894
1895 /* If RichCursor encoding is used, we should prevent collisions
1896 between framebuffer updates and cursor drawing operations. */
1897 client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
1898 }
1899
1900 switch (rect.encoding) {
1901
1902 case rfbEncodingRaw: {
1903 int y=rect.r.y, h=rect.r.h;
1904
1905 bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8;
1906 linesToRead = RFB_BUFFER_SIZE / bytesPerLine;
1907
1908 while (h > 0) {
1909 if (linesToRead > h)
1910 linesToRead = h;
1911
1912 if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead))
1913 return FALSE;
1914
1915 CopyRectangle(client, (uint8_t *)client->buffer,
1916 rect.r.x, y, rect.r.w,linesToRead);
1917
1918 h -= linesToRead;
1919 y += linesToRead;
1920
1921 }
1922 } break;
1923
1924 case rfbEncodingCopyRect:
1925 {
1926 rfbCopyRect cr;
1927
1928 if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect))
1929 return FALSE;
1930
1931 cr.srcX = rfbClientSwap16IfLE(cr.srcX);
1932 cr.srcY = rfbClientSwap16IfLE(cr.srcY);
1933
1934 /* If RichCursor encoding is used, we should extend our
1935 "cursor lock area" (previously set to destination
1936 rectangle) to the source rectangle as well. */
1937 client->SoftCursorLockArea(client,
1938 cr.srcX, cr.srcY, rect.r.w, rect.r.h);
1939
1940 if (client->GotCopyRect != NULL) {
1941 client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1942 rect.r.x, rect.r.y);
1943 } else
1944 CopyRectangleFromRectangle(client,
1945 cr.srcX, cr.srcY, rect.r.w, rect.r.h,
1946 rect.r.x, rect.r.y);
1947
1948 break;
1949 }
1950
1951 case rfbEncodingRRE:
1952 {
1953 switch (client->format.bitsPerPixel) {
1954 case 8:
1955 if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1956 return FALSE;
1957 break;
1958 case 16:
1959 if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1960 return FALSE;
1961 break;
1962 case 32:
1963 if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1964 return FALSE;
1965 break;
1966 }
1967 break;
1968 }
1969
1970 case rfbEncodingCoRRE:
1971 {
1972 switch (client->format.bitsPerPixel) {
1973 case 8:
1974 if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1975 return FALSE;
1976 break;
1977 case 16:
1978 if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1979 return FALSE;
1980 break;
1981 case 32:
1982 if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1983 return FALSE;
1984 break;
1985 }
1986 break;
1987 }
1988
1989 case rfbEncodingHextile:
1990 {
1991 switch (client->format.bitsPerPixel) {
1992 case 8:
1993 if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1994 return FALSE;
1995 break;
1996 case 16:
1997 if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1998 return FALSE;
1999 break;
2000 case 32:
2001 if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2002 return FALSE;
2003 break;
2004 }
2005 break;
2006 }
2007
2008 case rfbEncodingUltra:
2009 {
2010 switch (client->format.bitsPerPixel) {
2011 case 8:
2012 if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2013 return FALSE;
2014 break;
2015 case 16:
2016 if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2017 return FALSE;
2018 break;
2019 case 32:
2020 if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2021 return FALSE;
2022 break;
2023 }
2024 break;
2025 }
2026 case rfbEncodingUltraZip:
2027 {
2028 switch (client->format.bitsPerPixel) {
2029 case 8:
2030 if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2031 return FALSE;
2032 break;
2033 case 16:
2034 if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2035 return FALSE;
2036 break;
2037 case 32:
2038 if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2039 return FALSE;
2040 break;
2041 }
2042 break;
2043 }
2044
2045 #ifdef LIBVNCSERVER_HAVE_LIBZ
2046 case rfbEncodingZlib:
2047 {
2048 switch (client->format.bitsPerPixel) {
2049 case 8:
2050 if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2051 return FALSE;
2052 break;
2053 case 16:
2054 if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2055 return FALSE;
2056 break;
2057 case 32:
2058 if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2059 return FALSE;
2060 break;
2061 }
2062 break;
2063 }
2064
2065 #ifdef LIBVNCSERVER_HAVE_LIBJPEG
2066 case rfbEncodingTight:
2067 {
2068 switch (client->format.bitsPerPixel) {
2069 case 8:
2070 if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2071 return FALSE;
2072 break;
2073 case 16:
2074 if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2075 return FALSE;
2076 break;
2077 case 32:
2078 if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2079 return FALSE;
2080 break;
2081 }
2082 break;
2083 }
2084 #endif
2085 case rfbEncodingZRLE:
2086 /* Fail safe for ZYWRLE unsupport VNC server. */
2087 client->appData.qualityLevel = 9;
2088 /* fall through */
2089 case rfbEncodingZYWRLE:
2090 {
2091 switch (client->format.bitsPerPixel) {
2092 case 8:
2093 if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2094 return FALSE;
2095 break;
2096 case 16:
2097 if (client->si.format.greenMax > 0x1F) {
2098 if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2099 return FALSE;
2100 } else {
2101 if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2102 return FALSE;
2103 }
2104 break;
2105 case 32:
2106 {
2107 uint32_t maxColor=(client->format.redMax<<client->format.redShift)|
2108 (client->format.greenMax<<client->format.greenShift)|
2109 (client->format.blueMax<<client->format.blueShift);
2110 if ((client->format.bigEndian && (maxColor&0xff)==0) ||
2111 (!client->format.bigEndian && (maxColor&0xff000000)==0)) {
2112 if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2113 return FALSE;
2114 } else if (!client->format.bigEndian && (maxColor&0xff)==0) {
2115 if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2116 return FALSE;
2117 } else if (client->format.bigEndian && (maxColor&0xff000000)==0) {
2118 if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2119 return FALSE;
2120 } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h))
2121 return FALSE;
2122 break;
2123 }
2124 }
2125 break;
2126 }
2127
2128 #endif
2129
2130 default:
2131 {
2132 rfbBool handled = FALSE;
2133 rfbClientProtocolExtension* e;
2134
2135 for(e = rfbClientExtensions; !handled && e; e = e->next)
2136 if(e->handleEncoding && e->handleEncoding(client, &rect))
2137 handled = TRUE;
2138
2139 if(!handled) {
2140 rfbClientLog("Unknown rect encoding %d\n",
2141 (int)rect.encoding);
2142 return FALSE;
2143 }
2144 }
2145 }
2146
2147 /* Now we may discard "soft cursor locks". */
2148 client->SoftCursorUnlockScreen(client);
2149
2150 client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h);
2151 }
2152
2153 if (!SendIncrementalFramebufferUpdateRequest(client))
2154 return FALSE;
2155
2156 if (client->FinishedFrameBufferUpdate)
2157 client->FinishedFrameBufferUpdate(client);
2158
2159 break;
2160 }
2161
2162 case rfbBell:
2163 {
2164 client->Bell(client);
2165
2166 break;
2167 }
2168
2169 case rfbServerCutText:
2170 {
2171 char *buffer;
2172
2173 if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2174 sz_rfbServerCutTextMsg - 1))
2175 return FALSE;
2176
2177 msg.sct.length = rfbClientSwap32IfLE(msg.sct.length);
2178
2179 buffer = malloc(msg.sct.length+1);
2180
2181 if (!ReadFromRFBServer(client, buffer, msg.sct.length))
2182 return FALSE;
2183
2184 buffer[msg.sct.length] = 0;
2185
2186 if (client->GotXCutText)
2187 client->GotXCutText(client, buffer, msg.sct.length);
2188
2189 free(buffer);
2190
2191 break;
2192 }
2193
2194 case rfbTextChat:
2195 {
2196 char *buffer=NULL;
2197 if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2198 sz_rfbTextChatMsg- 1))
2199 return FALSE;
2200 msg.tc.length = rfbClientSwap32IfLE(msg.sct.length);
2201 switch(msg.tc.length) {
2202 case rfbTextChatOpen:
2203 rfbClientLog("Received TextChat Open\n");
2204 if (client->HandleTextChat!=NULL)
2205 client->HandleTextChat(client, (int)rfbTextChatOpen, NULL);
2206 break;
2207 case rfbTextChatClose:
2208 rfbClientLog("Received TextChat Close\n");
2209 if (client->HandleTextChat!=NULL)
2210 client->HandleTextChat(client, (int)rfbTextChatClose, NULL);
2211 break;
2212 case rfbTextChatFinished:
2213 rfbClientLog("Received TextChat Finished\n");
2214 if (client->HandleTextChat!=NULL)
2215 client->HandleTextChat(client, (int)rfbTextChatFinished, NULL);
2216 break;
2217 default:
2218 buffer=malloc(msg.tc.length+1);
2219 if (!ReadFromRFBServer(client, buffer, msg.tc.length))
2220 {
2221 free(buffer);
2222 return FALSE;
2223 }
2224 /* Null Terminate <just in case> */
2225 buffer[msg.tc.length]=0;
2226 rfbClientLog("Received TextChat \"%s\"\n", buffer);
2227 if (client->HandleTextChat!=NULL)
2228 client->HandleTextChat(client, (int)msg.tc.length, buffer);
2229 free(buffer);
2230 break;
2231 }
2232 break;
2233 }
2234
2235 case rfbXvp:
2236 {
2237 if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2238 sz_rfbXvpMsg -1))
2239 return FALSE;
2240
2241 SetClient2Server(client, rfbXvp);
2242 /* technically, we only care what we can *send* to the server
2243 * but, we set Server2Client Just in case it ever becomes useful
2244 */
2245 SetServer2Client(client, rfbXvp);
2246
2247 if(client->HandleXvpMsg)
2248 client->HandleXvpMsg(client, msg.xvp.version, msg.xvp.code);
2249
2250 break;
2251 }
2252
2253 case rfbResizeFrameBuffer:
2254 {
2255 if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2256 sz_rfbResizeFrameBufferMsg -1))
2257 return FALSE;
2258 client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth);
2259 client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth);
2260 client->updateRect.x = client->updateRect.y = 0;
2261 client->updateRect.w = client->width;
2262 client->updateRect.h = client->height;
2263 client->MallocFrameBuffer(client);
2264 SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
2265 rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
2266 break;
2267 }
2268
2269 case rfbPalmVNCReSizeFrameBuffer:
2270 {
2271 if (!ReadFromRFBServer(client, ((char *)&msg) + 1,
2272 sz_rfbPalmVNCReSizeFrameBufferMsg -1))
2273 return FALSE;
2274 client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w);
2275 client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h);
2276 client->updateRect.x = client->updateRect.y = 0;
2277 client->updateRect.w = client->width;
2278 client->updateRect.h = client->height;
2279 client->MallocFrameBuffer(client);
2280 SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE);
2281 rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height);
2282 break;
2283 }
2284
2285 default:
2286 {
2287 rfbBool handled = FALSE;
2288 rfbClientProtocolExtension* e;
2289
2290 for(e = rfbClientExtensions; !handled && e; e = e->next)
2291 if(e->handleMessage && e->handleMessage(client, &msg))
2292 handled = TRUE;
2293
2294 if(!handled) {
2295 char buffer[256];
2296 rfbClientLog("Unknown message type %d from VNC server\n",msg.type);
2297 ReadFromRFBServer(client, buffer, 256);
2298 return FALSE;
2299 }
2300 }
2301 }
2302
2303 return TRUE;
2304 }
2305
2306
2307 #define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
2308
2309 #define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
2310 ((uint8_t*)&(pix))[1] = *(ptr)++)
2311
2312 #define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \
2313 ((uint8_t*)&(pix))[1] = *(ptr)++, \
2314 ((uint8_t*)&(pix))[2] = *(ptr)++, \
2315 ((uint8_t*)&(pix))[3] = *(ptr)++)
2316
2317 /* CONCAT2 concatenates its two arguments. CONCAT2E does the same but also
2318 expands its arguments if they are macros */
2319
2320 #define CONCAT2(a,b) a##b
2321 #define CONCAT2E(a,b) CONCAT2(a,b)
2322 #define CONCAT3(a,b,c) a##b##c
2323 #define CONCAT3E(a,b,c) CONCAT3(a,b,c)
2324
2325 #define BPP 8
2326 #include "rre.c"
2327 #include "corre.c"
2328 #include "hextile.c"
2329 #include "ultra.c"
2330 #include "zlib.c"
2331 #include "tight.c"
2332 #include "zrle.c"
2333 #undef BPP
2334 #define BPP 16
2335 #include "rre.c"
2336 #include "corre.c"
2337 #include "hextile.c"
2338 #include "ultra.c"
2339 #include "zlib.c"
2340 #include "tight.c"
2341 #include "zrle.c"
2342 #define REALBPP 15
2343 #include "zrle.c"
2344 #undef BPP
2345 #define BPP 32
2346 #include "rre.c"
2347 #include "corre.c"
2348 #include "hextile.c"
2349 #include "ultra.c"
2350 #include "zlib.c"
2351 #include "tight.c"
2352 #include "zrle.c"
2353 #define REALBPP 24
2354 #include "zrle.c"
2355 #define REALBPP 24
2356 #define UNCOMP 8
2357 #include "zrle.c"
2358 #define REALBPP 24
2359 #define UNCOMP -8
2360 #include "zrle.c"
2361 #undef BPP
2362
2363
2364 /*
2365 * PrintPixelFormat.
2366 */
2367
2368 void
PrintPixelFormat(rfbPixelFormat * format)2369 PrintPixelFormat(rfbPixelFormat *format)
2370 {
2371 if (format->bitsPerPixel == 1) {
2372 rfbClientLog(" Single bit per pixel.\n");
2373 rfbClientLog(
2374 " %s significant bit in each byte is leftmost on the screen.\n",
2375 (format->bigEndian ? "Most" : "Least"));
2376 } else {
2377 rfbClientLog(" %d bits per pixel.\n",format->bitsPerPixel);
2378 if (format->bitsPerPixel != 8) {
2379 rfbClientLog(" %s significant byte first in each pixel.\n",
2380 (format->bigEndian ? "Most" : "Least"));
2381 }
2382 if (format->trueColour) {
2383 rfbClientLog(" TRUE colour: max red %d green %d blue %d"
2384 ", shift red %d green %d blue %d\n",
2385 format->redMax, format->greenMax, format->blueMax,
2386 format->redShift, format->greenShift, format->blueShift);
2387 } else {
2388 rfbClientLog(" Colour map (not true colour).\n");
2389 }
2390 }
2391 }
2392
2393 /* avoid name clashes with LibVNCServer */
2394
2395 #define rfbEncryptBytes rfbClientEncryptBytes
2396 #define rfbEncryptBytes2 rfbClientEncryptBytes2
2397 #define rfbDes rfbClientDes
2398 #define rfbDesKey rfbClientDesKey
2399 #define rfbUseKey rfbClientUseKey
2400 #define rfbCPKey rfbClientCPKey
2401
2402 #include "vncauth.c"
2403 #include "d3des.c"
2404