]> git.pld-linux.org Git - packages/directvnc.git/blame - directvnc-3.3.7-tight.patch
- added the 3.3.7-tight patch
[packages/directvnc.git] / directvnc-3.3.7-tight.patch
CommitLineData
3f615518 1diff -Nru directvnc-0.7.5/src/caps.c directvnc-0.7.5.new/src/caps.c
2--- directvnc-0.7.5/src/caps.c 1970-01-01 01:00:00.000000000 +0100
3+++ directvnc-0.7.5.new/src/caps.c 2007-01-15 14:48:51.000000000 +0100
4@@ -0,0 +1,246 @@
5+/*
6+ * Copyright (C) 2003 Constantin Kaplinsky. All Rights Reserved.
7+ *
8+ * This is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; either version 2 of the License, or
11+ * (at your option) any later version.
12+ *
13+ * This software is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+ * GNU General Public License for more details.
17+ *
18+ * You should have received a copy of the GNU General Public License
19+ * along with this software; if not, write to the Free Software
20+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21+ * USA.
22+ */
23+
24+/*
25+ * caps.c
26+ */
27+
28+#include "caps.h"
29+#include "rfbproto.h"
30+
31+static int CapsIndex(CapsContainer *pcaps, CARD32 code);
32+
33+/*
34+ * The constructor.
35+ */
36+
37+CapsContainer *
38+CapsNewContainer(void)
39+{
40+ CapsContainer *pcaps;
41+
42+ pcaps = malloc(sizeof(CapsContainer));
43+ if (pcaps != NULL) {
44+ pcaps->known_count = 0;
45+ pcaps->enabled_count = 0;
46+ }
47+
48+ return pcaps;
49+}
50+
51+/*
52+ * The destructor.
53+ */
54+
55+void
56+CapsDeleteContainer(CapsContainer *pcaps)
57+{
58+ int i;
59+
60+ for (i = 0; i < pcaps->known_count; i++) {
61+ if (pcaps->descriptions[i] != NULL)
62+ free(pcaps->descriptions[i]);
63+ }
64+
65+ free(pcaps);
66+}
67+
68+/*
69+ * Add information about a particular capability into the object. There are
70+ * two functions to perform this task. These functions overwrite capability
71+ * records with the same code.
72+ */
73+
74+void
75+CapsAdd(CapsContainer *pcaps,
76+ CARD32 code, char *vendor, char *name, char *desc)
77+{
78+ /* Fill in an rfbCapabilityInfo structure and pass it to CapsAddInfo(). */
79+ rfbCapabilityInfo capinfo;
80+ capinfo.code = code;
81+ memcpy(capinfo.vendorSignature, vendor, sz_rfbCapabilityInfoVendor);
82+ memcpy(capinfo.nameSignature, name, sz_rfbCapabilityInfoName);
83+ CapsAddInfo(pcaps, &capinfo, desc);
84+}
85+
86+void
87+CapsAddInfo(CapsContainer *pcaps,
88+ rfbCapabilityInfo *capinfo, char *desc)
89+{
90+ int i;
91+ char *desc_copy;
92+
93+ i = CapsIndex(pcaps, capinfo->code);
94+ if (i == -1) {
95+ if (pcaps->known_count >= TIGHTVNC_MAX_CAPS) {
96+ return; /* container full */
97+ }
98+ i = pcaps->known_count++;
99+ pcaps->known_list[i] = capinfo->code;
100+ pcaps->descriptions[i] = NULL;
101+ }
102+
103+ pcaps->known_info[i] = *capinfo;
104+ pcaps->enable_flags[i] = (char)0;
105+ if (pcaps->descriptions[i] != NULL) {
106+ free(pcaps->descriptions[i]);
107+ }
108+
109+ desc_copy = NULL;
110+ if (desc != NULL) {
111+ desc_copy = strdup(desc);
112+ }
113+ pcaps->descriptions[i] = desc_copy;
114+}
115+
116+/*
117+ * Check if a capability with the specified code was added earlier.
118+ */
119+
120+static int
121+CapsIndex(CapsContainer *pcaps, CARD32 code)
122+{
123+ int i;
124+
125+ for (i = 0; i < pcaps->known_count; i++) {
126+ if (pcaps->known_list[i] == code)
127+ return i;
128+ }
129+
130+ return -1;
131+}
132+
133+int
134+CapsIsKnown(CapsContainer *pcaps, CARD32 code)
135+{
136+ return (CapsIndex(pcaps, code) != -1);
137+}
138+
139+/*
140+ * Fill in a rfbCapabilityInfo structure with contents corresponding to the
141+ * specified code. Returns True on success, False if the specified code is
142+ * not known.
143+ */
144+
145+int
146+CapsGetInfo(CapsContainer *pcaps, CARD32 code, rfbCapabilityInfo *capinfo)
147+{
148+ int i;
149+
150+ i = CapsIndex(pcaps, code);
151+ if (i != -1) {
152+ *capinfo = pcaps->known_info[i];
153+ return 1;
154+ }
155+
156+ return 0;
157+}
158+
159+/*
160+ * Get a description string for the specified capability code. Returns NULL
161+ * either if the code is not known, or if there is no description for this
162+ * capability.
163+ */
164+
165+char *
166+CapsGetDescription(CapsContainer *pcaps, CARD32 code)
167+{
168+ int i;
169+
170+ i = CapsIndex(pcaps, code);
171+ if (i != -1) {
172+ return pcaps->descriptions[i];
173+ }
174+
175+ return NULL;
176+}
177+
178+/*
179+ * Mark the specified capability as "enabled". This function checks "vendor"
180+ * and "name" signatures in the existing record and in the argument structure
181+ * and enables the capability only if both records are the same.
182+ */
183+
184+int
185+CapsEnable(CapsContainer *pcaps, rfbCapabilityInfo *capinfo)
186+{
187+ int i;
188+ rfbCapabilityInfo *known;
189+
190+ i = CapsIndex(pcaps, capinfo->code);
191+ if (i == -1)
192+ return 0;
193+
194+ known = &pcaps->known_info[i];
195+ if ( memcmp(known->vendorSignature, capinfo->vendorSignature,
196+ sz_rfbCapabilityInfoVendor) != 0 ||
197+ memcmp(known->nameSignature, capinfo->nameSignature,
198+ sz_rfbCapabilityInfoName) != 0 ) {
199+ pcaps->enable_flags[i] = (char)0;
200+ return 0;
201+ }
202+
203+ /* Cannot happen, but just in case. */
204+ if (pcaps->enabled_count >= TIGHTVNC_MAX_CAPS) {
205+ pcaps->enable_flags[i] = (char)0;
206+ return 0;
207+ }
208+
209+ pcaps->enable_flags[i] = (char)1;
210+ pcaps->enabled_list[pcaps->enabled_count++] = capinfo->code;
211+ return 1;
212+}
213+
214+/*
215+ * Check if the specified capability is known and enabled.
216+ */
217+
218+int
219+CapsIsEnabled(CapsContainer *pcaps, CARD32 code)
220+{
221+ int i;
222+
223+ i = CapsIndex(pcaps, code);
224+ if (i != -1) {
225+ return (pcaps->enable_flags[i] != (char)0);
226+ }
227+
228+ return 0;
229+}
230+
231+/*
232+ * Return the number of enabled capabilities.
233+ */
234+
235+int CapsNumEnabled(CapsContainer *pcaps)
236+{
237+ return pcaps->enabled_count;
238+}
239+
240+/*
241+ * Return the capability code at the specified index.
242+ * If the index is not valid, return 0.
243+ */
244+
245+CARD32
246+CapsGetByOrder(CapsContainer *pcaps, int idx)
247+{
248+ return (idx < pcaps->enabled_count) ? pcaps->enabled_list[idx] : 0;
249+}
250+
251diff -Nru directvnc-0.7.5/src/caps.h directvnc-0.7.5.new/src/caps.h
252--- directvnc-0.7.5/src/caps.h 1970-01-01 01:00:00.000000000 +0100
253+++ directvnc-0.7.5.new/src/caps.h 2007-01-15 14:46:50.000000000 +0100
254@@ -0,0 +1,64 @@
255+/*
256+ * Copyright (C) 2003 Constantin Kaplinsky. All Rights Reserved.
257+ *
258+ * This is free software; you can redistribute it and/or modify
259+ * it under the terms of the GNU General Public License as published by
260+ * the Free Software Foundation; either version 2 of the License, or
261+ * (at your option) any later version.
262+ *
263+ * This software is distributed in the hope that it will be useful,
264+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
265+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
266+ * GNU General Public License for more details.
267+ *
268+ * You should have received a copy of the GNU General Public License
269+ * along with this software; if not, write to the Free Software
270+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
271+ * USA.
272+ */
273+
274+/*
275+ * caps.h
276+ */
277+
278+#ifndef _VNC_CAPSCONTAINER
279+#define _VNC_CAPSCONTAINER
280+
281+#include "directvnc.h"
282+/* FIXME: Don't limit the number of capabilities. */
283+#define TIGHTVNC_MAX_CAPS 64
284+
285+typedef struct _CapsContainer
286+{
287+ int known_count;
288+ CARD32 known_list[TIGHTVNC_MAX_CAPS];
289+ rfbCapabilityInfo known_info[TIGHTVNC_MAX_CAPS];
290+ char *descriptions[TIGHTVNC_MAX_CAPS];
291+ char enable_flags[TIGHTVNC_MAX_CAPS];
292+
293+ /* These are redundant, but improve the performance. */
294+ int enabled_count;
295+ CARD32 enabled_list[TIGHTVNC_MAX_CAPS];
296+
297+} CapsContainer;
298+
299+CapsContainer *CapsNewContainer(void);
300+void CapsDeleteContainer(CapsContainer *pcaps);
301+
302+void CapsAdd(CapsContainer *pcaps,
303+ CARD32 code, char *vendor, char *name, char *desc);
304+void CapsAddInfo(CapsContainer *pcaps,
305+ rfbCapabilityInfo *capinfo, char *desc);
306+
307+int CapsIsKnown(CapsContainer *pcaps, CARD32 code);
308+int CapsGetInfo(CapsContainer *pcaps, CARD32 code,
309+ rfbCapabilityInfo *capinfo);
310+char *CapsGetDescription(CapsContainer *pcaps, CARD32 code);
311+
312+int CapsEnable(CapsContainer *pcaps, rfbCapabilityInfo *capinfo);
313+int CapsIsEnabled(CapsContainer *pcaps, CARD32 code);
314+int CapsNumEnabled(CapsContainer *pcaps);
315+CARD32 CapsGetByOrder(CapsContainer *pcaps, int idx);
316+
317+#endif /* _VNC_CAPSCONTAINER */
318+
319diff -Nru directvnc-0.7.5/src/cursor.c directvnc-0.7.5.new/src/cursor.c
320--- directvnc-0.7.5/src/cursor.c 2003-01-26 19:47:54.000000000 +0100
321+++ directvnc-0.7.5.new/src/cursor.c 2007-01-15 19:59:32.000000000 +0100
322@@ -31,6 +31,15 @@
323 #define True 1
324 #define False 0
325
326+#define RGB24_TO_PIXEL(bpp,r,g,b) \
327+ ((((CARD##bpp)(r) & 0xFF) * opt.client.redmax + 127) / 255 \
328+ << opt.client.redshift | \
329+ (((CARD##bpp)(g) & 0xFF) * opt.client.greenmax + 127) / 255 \
330+ << opt.client.greenshift | \
331+ (((CARD##bpp)(b) & 0xFF) * opt.client.bluemax + 127) / 255 \
332+ << opt.client.blueshift)
333+
334+
335
336 /* Data kept for RichCursor encoding support. */
337 static Bool prevRichCursorSet = False;
338@@ -46,7 +55,6 @@
339 static void SoftCursorDraw(void);
340 static void FreeCursors(Bool setDotCursor);
341
342-
343 /*********************************************************************
344 * HandleRichCursor(). RichCursor shape updates support. This
345 * variation of cursor shape updates cannot be supported directly via
346@@ -54,13 +62,17 @@
347 * buffer (that is why we call it "software cursor").
348 ********************************************************************/
349
350-Bool HandleRichCursor(int xhot, int yhot, int width, int height)
351+Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc)
352 {
353+ int bytesPerPixel;
354 size_t bytesPerRow, bytesMaskData;
355+ rfbXCursorColors rgb;
356+ CARD32 colors[2];
357 char *buf;
358 CARD8 *ptr;
359 int x, y, b;
360
361+ bytesPerPixel = opt.server.bpp / 8;
362 bytesPerRow = (width + 7) / 8;
363 bytesMaskData = bytesPerRow * height;
364
365@@ -75,11 +87,6 @@
366 if (rcSource == NULL)
367 return False;
368
369- if (!read_from_rfb_server(sock, (char *)rcSource,
370- width * height * (opt.client.bpp / 8))) {
371- free(rcSource);
372- return False;
373- }
374
375 /* Read and decode mask data. */
376
377@@ -89,6 +96,64 @@
378 return False;
379 }
380
381+ /* Read and decode cursor pixel data, depending on the encoding type. */
382+
383+ if (enc == rfbEncodingXCursor) {
384+
385+ /* Read and convert background and foreground colors. */
386+ if (!read_from_rfb_server(sock, (char *)&rgb, sz_rfbXCursorColors)) {
387+ free(rcSource);
388+ free(buf);
389+ return False;
390+ }
391+ colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
392+ colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);
393+
394+ /* Read 1bpp pixel data into a temporary buffer. */
395+ if (!read_from_rfb_server(sock, buf, bytesMaskData)) {
396+ free(rcSource);
397+ free(buf);
398+ return False;
399+ }
400+
401+ /* Convert 1bpp data to byte-wide color indices. */
402+ ptr = rcSource;
403+ for (y = 0; y < height; y++) {
404+ for (x = 0; x < width / 8; x++) {
405+ for (b = 7; b >= 0; b--) {
406+ *ptr = buf[y * bytesPerRow + x] >> b & 1;
407+ ptr += bytesPerPixel;
408+ }
409+ }
410+ for (b = 7; b > 7 - width % 8; b--) {
411+ *ptr = buf[y * bytesPerRow + x] >> b & 1;
412+ ptr += bytesPerPixel;
413+ }
414+ }
415+
416+ /* Convert indices into the actual pixel values. */
417+ switch (bytesPerPixel) {
418+ case 1:
419+ for (x = 0; x < width * height; x++)
420+ rcSource[x] = (CARD8)colors[rcSource[x]];
421+ break;
422+ case 2:
423+ for (x = 0; x < width * height; x++)
424+ ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]];
425+ break;
426+ case 4:
427+ for (x = 0; x < width * height; x++)
428+ ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]];
429+ break;
430+ }
431+ } else { /* rfbEncodingRichCursor */
432+ if (!read_from_rfb_server(sock, (char *)rcSource,
433+ width * height * (opt.client.bpp / 8))) {
434+ free(rcSource);
435+ return False;
436+ }
437+ }
438+
439 if (!read_from_rfb_server(sock, buf, bytesMaskData)) {
440 free(rcSource);
441 free(buf);
442@@ -201,7 +266,8 @@
443 * SoftCursorUnlock() functions is called.
444 ********************************************************************/
445
446-void SoftCursorMove(int x, int y)
447+void
448+SoftCursorMove(int x, int y)
449 {
450 if (prevRichCursorSet && !rcCursorHidden) {
451 SoftCursorCopyArea(OPER_RESTORE);
452@@ -303,3 +369,20 @@
453 }
454 }
455
456+/*********************************************************************
457+ * HandleCursorPos(). Support for the PointerPos pseudo-encoding used
458+ * to transmit changes in pointer position from server to clients.
459+ * PointerPos encoding is used together with cursor shape updates.
460+ ********************************************************************/
461+
462+int
463+HandleCursorPos(int x, int y)
464+{
465+ if (x >= opt.server.width)
466+ x = opt.server.width - 1;
467+ if (y >= opt.server.height)
468+ y = opt.server.height - 1;
469+
470+ SoftCursorMove(x, y);
471+ return 1;
472+}
473diff -Nru directvnc-0.7.5/src/directvnc.h directvnc-0.7.5.new/src/directvnc.h
474--- directvnc-0.7.5/src/directvnc.h 2007-01-15 22:06:18.000000000 +0100
475+++ directvnc-0.7.5.new/src/directvnc.h 2007-01-15 20:02:12.000000000 +0100
476@@ -117,6 +117,7 @@
477 {
478 char *servername;
479 int port;
480+ char *user;
481 char *password;
482 char *encodings;
483 struct serversettings server;
484@@ -142,6 +143,7 @@
485 int read_from_rfb_server(int sock, char *out, unsigned int n);
486 int write_exact(int sock, char *buf, unsigned int n);
487 int set_non_blocking(int sock);
488+int SameMachine(int sock);
489
490 /* dfb.c */
491 void dfb_init(int argc, char *argv[]);
492@@ -157,12 +159,11 @@
493 void dfb_restore_cursor_rect( IDirectFBSurface *surf, int x, int y, int width, int heigth);
494
495 /* cursor.c */
496-int HandleRichCursor(int x, int y, int w, int h);
497+int HandleCursorShape(int x, int y, int w, int h, CARD32 enc);
498 void SoftCursorLockArea(int x, int y, int w, int h);
499 void SoftCursorUnlockScreen(void);
500 void SoftCursorMove(int x, int y);
501
502-
503 /* macro for a safe call to DirectFB functions */
504 #define DFBCHECK(x...) \
505 { \
506@@ -174,5 +175,3 @@
507 }
508
509 #endif
510-
511-
512diff -Nru directvnc-0.7.5/src/Makefile.am directvnc-0.7.5.new/src/Makefile.am
513--- directvnc-0.7.5/src/Makefile.am 2003-01-31 10:20:35.000000000 +0100
514+++ directvnc-0.7.5.new/src/Makefile.am 2007-01-15 14:07:50.000000000 +0100
515@@ -9,7 +9,7 @@
516 LIBOBJS = @LIBOBJS@
517
518 bin_PROGRAMS = directvnc
519-directvnc_SOURCES = main.c debug.h dfb.c directvnc.h sockets.c args.c\
520+directvnc_SOURCES = caps.c caps.h main.c debug.h dfb.c directvnc.h sockets.c args.c\
521 rfb.c getopt.c getopt1.c getopt.h\
522 d3des.c d3des.h vncauth.c vncauth.h jpeg.c jpeg.h\
523 tight.c tight.h rfbproto.h keysym.h keysymdef.h \
524diff -Nru directvnc-0.7.5/src/rfb.c directvnc-0.7.5.new/src/rfb.c
525--- directvnc-0.7.5/src/rfb.c 2003-01-31 09:41:03.000000000 +0100
526+++ directvnc-0.7.5.new/src/rfb.c 2007-01-15 21:49:58.000000000 +0100
527@@ -17,7 +17,8 @@
528 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
529 */
530
531-
532+#include <pwd.h>
533+#include <sys/types.h>
534 #include <unistd.h>
535 #include <sys/socket.h>
536 #include <errno.h>
537@@ -28,15 +29,25 @@
538 #include <math.h>
539 #include <zlib.h>
540
541+#include "caps.h"
542 #include "directvnc.h"
543 #include "tight.h"
544
545+static void InitCapabilities(void);
546+static int SetupTunneling(void);
547+static int ReadSecurityType(void);
548+static int SelectSecurityType(void);
549+static int PerformAuthenticationTight(void);
550+static int AuthenticateVNC(void);
551+static int AuthenticateUnixLogin(void);
552+static int ReadInteractionCaps(void);
553+static int ReadCapabilityList(CapsContainer *caps, int count);
554+
555 int _rfb_negotiate_protocol ();
556 int _rfb_authenticate ();
557 int _rfb_initialise_client ();
558 int _rfb_initialise_server ();
559
560-
561 static int _handle_raw_encoded_message(rfbFramebufferUpdateRectHeader rectheader);
562 static int _handle_copyrect_encoded_message(rfbFramebufferUpdateRectHeader rectheader);
563 static int _handle_rre_encoded_message(rfbFramebufferUpdateRectHeader rectheader);
564@@ -44,6 +55,63 @@
565 static int _handle_hextile_encoded_message(rfbFramebufferUpdateRectHeader rectheader);
566 static int _handle_richcursor_message(rfbFramebufferUpdateRectHeader rectheader);
567
568+static int tightVncProtocol = 0;
569+static CapsContainer *tunnelCaps; /* known tunneling/encryption methods */
570+static CapsContainer *authCaps; /* known authentication schemes */
571+static CapsContainer *serverMsgCaps; /* known non-standard server messages */
572+static CapsContainer *clientMsgCaps; /* known non-standard client messages */
573+static CapsContainer *encodingCaps; /* known encodings besides Raw */
574+static int tunnelSpecified = 0;
575+
576+/*
577+ * InitCapabilities.
578+ */
579+
580+static void
581+InitCapabilities(void)
582+{
583+ tunnelCaps = CapsNewContainer();
584+ authCaps = CapsNewContainer();
585+ serverMsgCaps = CapsNewContainer();
586+ clientMsgCaps = CapsNewContainer();
587+ encodingCaps = CapsNewContainer();
588+
589+ /* Supported authentication methods */
590+ CapsAdd(authCaps, rfbAuthVNC, rfbStandardVendor, sig_rfbAuthVNC,
591+ "Standard VNC password authentication");
592+ CapsAdd(authCaps, rfbAuthUnixLogin, rfbTightVncVendor, sig_rfbAuthUnixLogin,
593+ "Login-style Unix authentication");
594+
595+ /* Supported encoding types */
596+ CapsAdd(encodingCaps, rfbEncodingCopyRect, rfbStandardVendor,
597+ sig_rfbEncodingCopyRect, "Standard CopyRect encoding");
598+ CapsAdd(encodingCaps, rfbEncodingRRE, rfbStandardVendor,
599+ sig_rfbEncodingRRE, "Standard RRE encoding");
600+ CapsAdd(encodingCaps, rfbEncodingCoRRE, rfbStandardVendor,
601+ sig_rfbEncodingCoRRE, "Standard CoRRE encoding");
602+ CapsAdd(encodingCaps, rfbEncodingHextile, rfbStandardVendor,
603+ sig_rfbEncodingHextile, "Standard Hextile encoding");
604+ CapsAdd(encodingCaps, rfbEncodingZlib, rfbTridiaVncVendor,
605+ sig_rfbEncodingZlib, "Zlib encoding from TridiaVNC");
606+ CapsAdd(encodingCaps, rfbEncodingTight, rfbTightVncVendor,
607+ sig_rfbEncodingTight, "Tight encoding by Constantin Kaplinsky");
608+
609+ /* Supported "fake" encoding types */
610+ CapsAdd(encodingCaps, rfbEncodingCompressLevel0, rfbTightVncVendor,
611+ sig_rfbEncodingCompressLevel0, "Compression level");
612+ CapsAdd(encodingCaps, rfbEncodingQualityLevel0, rfbTightVncVendor,
613+ sig_rfbEncodingQualityLevel0, "JPEG quality level");
614+ CapsAdd(encodingCaps, rfbEncodingXCursor, rfbTightVncVendor,
615+ sig_rfbEncodingXCursor, "X-style cursor shape update");
616+ CapsAdd(encodingCaps, rfbEncodingRichCursor, rfbTightVncVendor,
617+ sig_rfbEncodingRichCursor, "Rich-color cursor shape update");
618+ CapsAdd(encodingCaps, rfbEncodingPointerPos, rfbTightVncVendor,
619+ sig_rfbEncodingPointerPos, "Pointer position update");
620+ CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor,
621+ sig_rfbEncodingLastRect, "LastRect protocol extension");
622+}
623+
624+
625 /*
626 * ConnectToRFBServer.
627 */
628@@ -100,89 +168,393 @@
629 int
630 rfb_initialise_connection ()
631 {
632- if (!_rfb_negotiate_protocol()) return 0;
633- if (!_rfb_authenticate()) return 0;
634- if (!_rfb_initialise_client()) return 0;
635- if (!_rfb_initialise_server()) return 0;
636-
637- return(1);
638+ if (!_rfb_negotiate_protocol()) return 0;
639+ if (!_rfb_initialise_client()) return 0;
640+ if (!_rfb_initialise_server()) return 0;
641+ return 1;
642 }
643
644 int
645 _rfb_negotiate_protocol()
646 {
647 rfbProtocolVersionMsg msg;
648+ int server_major, server_minor;
649+ int viewer_major, viewer_minor;
650+ int secType;
651
652 /* read the protocol version the server uses */
653 if (!read_from_rfb_server(sock, (char*)&msg, sz_rfbProtocolVersionMsg))
654 return 0;
655- /* FIXME actually do something with that information ;) */
656
657+ msg[sz_rfbProtocolVersionMsg] = 0;
658+
659+ if (sscanf(msg, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) {
660+ return 0;
661+ }
662+ viewer_major = rfbProtocolMajorVersion;
663+ if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) {
664+ /* the server supports at least the standard protocol 3.7 */
665+ viewer_minor = rfbProtocolMinorVersion;
666+ } else {
667+ /* any other server version, request the standard 3.3 */
668+ viewer_minor = rfbProtocolFallbackMinorVersion;
669+ }
670 /* send the protocol version we want to use */
671- sprintf(msg, rfbProtocolVersionFormat,
672- rfbProtocolMajorVersion,
673- rfbProtocolMinorVersion);
674+ sprintf(msg, rfbProtocolVersionFormat,
675+ viewer_major,
676+ viewer_minor);
677 if (!write_exact (sock, msg, sz_rfbProtocolVersionMsg))
678 return 0;
679
680- return 1;
681+ /* Read or select the security type. */
682+ if (viewer_minor == rfbProtocolMinorVersion) {
683+ secType = SelectSecurityType();
684+ } else {
685+ secType = ReadSecurityType();
686+ }
687+ if (secType == rfbConnFailed)
688+ return 0;
689+
690+ return _rfb_authenticate(secType);
691 }
692
693+static int
694+ReadSecurityType(void)
695+{
696+ CARD32 secType;
697+ if (!read_from_rfb_server(sock, (char *)&secType, sizeof(secType))) {
698+ return rfbConnFailed;
699+ }
700+ return Swap32IfLE(secType);
701+}
702
703-int
704-_rfb_authenticate()
705+static int
706+SelectSecurityType(void)
707 {
708- CARD32 authscheme;
709-
710- read_from_rfb_server(sock, (char *)&authscheme, 4);
711- authscheme = Swap32IfLE(authscheme);
712- switch (authscheme)
713- {
714- CARD32 reason_length;
715- CARD8 *reason_string;
716- CARD8 challenge_and_response[CHALLENGESIZE];
717- CARD32 auth_result;
718-
719- case rfbConnFailed:
720- fprintf(stderr, "DIRECTVNC: Connection to VNC server failed\n");
721- read_from_rfb_server(sock, (char *)&reason_length, 4);
722- reason_length = Swap32IfLE(reason_length);
723- reason_string = malloc(sizeof(CARD8) * reason_length);
724- read_from_rfb_server(sock, (char *)reason_string, reason_length);
725- fprintf(stderr, "Errormessage: %s\n", reason_string);
726- return (0);
727- case rfbVncAuth:
728+ CARD8 nSecTypes;
729+ char *secTypeNames[] = {"None", "VncAuth"};
730+ CARD8 knownSecTypes[] = {rfbNoAuth, rfbVncAuth};
731+ int nKnownSecTypes = sizeof(knownSecTypes);
732+ CARD8 *secTypes;
733+ CARD8 secType = rfbConnFailed;
734+ int i, j;
735+
736+ /* Read the list of security types. */
737+ if (!read_from_rfb_server(sock, (char *)&nSecTypes, sizeof(nSecTypes)))
738+ return rfbConnFailed;
739+ if (nSecTypes == 0) {
740+ return rfbConnFailed;
741+ }
742+
743+ secTypes = malloc(nSecTypes);
744+ if (!read_from_rfb_server(sock, (char *)secTypes, nSecTypes))
745+ return rfbConnFailed;
746+
747+ /* Find out if the server supports TightVNC protocol extensions */
748+ for (j = 0; j < (int)nSecTypes; j++) {
749+ if (secTypes[j] == rfbSecTypeTight) {
750+ free(secTypes);
751+ secType = rfbSecTypeTight;
752+ if (!write_exact(sock, (char *)&secType, sizeof(secType)))
753+ return rfbConnFailed;
754+ fprintf(stderr, "Enabling TightVNC protocol extensions\n");
755+ return rfbSecTypeTight;
756+ }
757+ }
758+ /* Find first supported security type */
759+ for (j = 0; j < (int)nSecTypes; j++) {
760+ for (i = 0; i < nKnownSecTypes; i++) {
761+ if (secTypes[j] == knownSecTypes[i]) {
762+ secType = secTypes[j];
763+ if (!write_exact(sock, (char *)&secType, sizeof(secType))) {
764+ free(secTypes);
765+ return rfbConnFailed;
766+ }
767+ break;
768+ }
769+ }
770+ if (secType != rfbConnFailed) break;
771+ }
772+ free(secTypes);
773+ if (secType == rfbConnFailed)
774+ fprintf(stderr, "Server did not offer supported security type\n");
775+ return (int)secType;
776
777- /* we didnt get a password on the command line, so go get one */
778- if (!opt.password) opt.password = getpass("Password: ");
779+}
780
781- if (!read_from_rfb_server(sock, challenge_and_response, CHALLENGESIZE))
782- return 0;
783- vncEncryptBytes(challenge_and_response, opt.password);
784- if (!write_exact(sock, challenge_and_response, CHALLENGESIZE))
785- return 0;
786- if (!read_from_rfb_server(sock, (char*)&auth_result, 4))
787+/*
788+ * Standard VNC authentication.
789+ */
790+
791+static int
792+AuthenticateVNC(void)
793+{
794+ CARD32 authScheme, auth_result;
795+ CARD8 challenge[CHALLENGESIZE];
796+ char *passwd;
797+ char buffer[64];
798+ char* cstatus;
799+ int len;
800+
801+ fprintf(stderr, "Performing standard VNC authentication\n");
802+
803+ if (!read_from_rfb_server(sock, (char *)challenge, CHALLENGESIZE))
804+ return 0;
805+
806+
807+ /* we get a password on the command line, so go get one */
808+ if (!opt.password) opt.password = getpass("Password: ");
809+ if (strlen(opt.password) > 8) {
810+ opt.password[8] = '\0';
811+ }
812+
813+ vncEncryptBytes(challenge, opt.password);
814+ /* Lose the password from memory */
815+ memset(opt.password, '\0', strlen(opt.password));
816+
817+ if (!write_exact(sock, challenge, CHALLENGESIZE))
818+ return 0;
819+ if (!read_from_rfb_server(sock, (char*)&auth_result, 4))
820 return 0;
821- auth_result = Swap32IfLE(auth_result);
822- switch (auth_result)
823- {
824- case rfbVncAuthFailed:
825- fprintf(stderr, "Authentication Failed\n");
826- return (0);
827- case rfbVncAuthTooMany:
828- fprintf(stderr, "Too many connections\n");
829- return (0);
830- case rfbVncAuthOK:
831- fprintf(stderr, "Authentication OK\n");
832- break;
833- }
834- break;
835- case rfbNoAuth:
836- break;
837+ auth_result = Swap32IfLE(auth_result);
838+ switch (auth_result) {
839+ case rfbVncAuthFailed:
840+ fprintf(stderr, "Authentication Failed\n");
841+ return 0;
842+ case rfbVncAuthTooMany:
843+ fprintf(stderr, "Too many connections\n");
844+ return 0;
845+ case rfbVncAuthOK:
846+ fprintf(stderr, "Authentication OK\n");
847+ break;
848+ }
849+ return 1;
850+}
851+
852+
853+/*
854+ * Read the list of rfbCapabilityInfo structures and enable corresponding
855+ * capabilities in the specified container. The count argument specifies how
856+ * many records to read from the socket.
857+ */
858+
859+static int
860+ReadCapabilityList(CapsContainer *caps, int count)
861+{
862+ rfbCapabilityInfo msginfo;
863+ int i;
864+
865+ for (i = 0; i < count; i++) {
866+ if (!read_from_rfb_server(sock, (char *)&msginfo, sz_rfbCapabilityInfo))
867+ return 0;
868+ msginfo.code = Swap32IfLE(msginfo.code);
869+ CapsEnable(caps, &msginfo);
870+ }
871+
872+ return 1;
873+}
874+
875+/*
876+ * Unix login-style authentication.
877+ */
878+
879+static int
880+AuthenticateUnixLogin(void)
881+{
882+ CARD32 loginLen, passwdLen, authResult;
883+ char *login;
884+ char *passwd;
885+ struct passwd *ps;
886+
887+ fprintf(stderr, "Performing Unix login-style authentication\n");
888+
889+ if (opt.user) {
890+ login = opt.user;
891+ } else {
892+ ps = getpwuid(getuid());
893+ login = ps->pw_name;
894+ }
895+
896+ fprintf(stderr, "Using user name \"%s\"\n", login);
897+
898+ passwd = getpass("Password: ");
899+
900+ if (!passwd || strlen(passwd) == 0) {
901+ fprintf(stderr, "Reading password failed\n");
902+ return 0;
903+ }
904+
905+ loginLen = Swap32IfLE((CARD32)strlen(login));
906+ passwdLen = Swap32IfLE((CARD32)strlen(passwd));
907+
908+ if (!write_exact(sock, (char *)&loginLen, sizeof(loginLen)) ||
909+ !write_exact(sock, (char *)&passwdLen, sizeof(passwdLen)))
910+ return 0;
911+
912+ if (!write_exact(sock, login, strlen(login)) ||
913+ !write_exact(sock, passwd, strlen(passwd)))
914+ return 0;
915+
916+ /* Lose the password from memory */
917+ memset(passwd, '\0', strlen(passwd));
918+
919+ if (!read_from_rfb_server(sock, (char *)&authResult, sizeof(authResult)))
920+ return 0;
921+
922+ authResult = Swap32IfLE(authResult);
923+
924+ switch (authResult) {
925+ case rfbVncAuthOK:
926+ fprintf(stderr, "Authentication succeeded\n");
927+ break;
928+ case rfbVncAuthFailed:
929+ fprintf(stderr, "Authentication failed\n");
930+ return 0;
931+ case rfbVncAuthTooMany:
932+ fprintf(stderr, "Authentication failed - too many tries\n");
933+ return 0;
934+ default:
935+ fprintf(stderr, "Unknown authentication result: %d\n",
936+ (int)authResult);
937+ return 0;
938+ }
939+
940+ return 1;
941+}
942+
943+
944+int
945+_rfb_authenticate(CARD32 authscheme)
946+{
947+ switch (authscheme) {
948+ CARD32 reason_length;
949+ CARD8 *reason_string;
950+ CARD8 challenge_and_response[CHALLENGESIZE];
951+ CARD32 auth_result;
952+
953+ case rfbConnFailed:
954+ fprintf(stderr, "DIRECTVNC: Connection to VNC server failed\n");
955+ read_from_rfb_server(sock, (char *)&reason_length, 4);
956+ reason_length = Swap32IfLE(reason_length);
957+ reason_string = malloc(sizeof(CARD8) * reason_length);
958+ read_from_rfb_server(sock, (char *)reason_string, reason_length);
959+ fprintf(stderr, "Errormessage: %s\n", reason_string);
960+ return 0;
961+ case rfbVncAuth:
962+ return AuthenticateVNC();
963+ case rfbNoAuth:
964+ break;
965+ case rfbSecTypeTight:
966+ tightVncProtocol = 1;
967+ InitCapabilities();
968+ if (!SetupTunneling()) return 0;
969+ if (!PerformAuthenticationTight()) return 0;
970+ break;
971+ default:
972+ fprintf(stderr, "Internal error: Invalid security type\n");
973+ return 0;
974 }
975 return 1;
976 }
977
978+static int
979+SetupTunneling(void)
980+{
981+ rfbTunnelingCapsMsg caps;
982+ CARD32 tunnelType;
983+
984+ /* In the protocol version 3.7t, the server informs us about
985+ supported tunneling methods. Here we read this information. */
986+
987+ if (!read_from_rfb_server(sock, (char *)&caps, sz_rfbTunnelingCapsMsg)) return 0;
988+ caps.nTunnelTypes = Swap32IfLE(caps.nTunnelTypes);
989+
990+ if (caps.nTunnelTypes) {
991+ if (!ReadCapabilityList(tunnelCaps, caps.nTunnelTypes)) return 0;
992+
993+ /* We cannot do tunneling anyway yet. */
994+ tunnelType = Swap32IfLE(rfbNoTunneling);
995+ if (!write_exact(sock, (char *)&tunnelType, sizeof(tunnelType))) return 0;
996+ }
997+ return 1;
998+}
999+
1000+/* Negotiate authentication scheme (protocol version 3.7t) */
1001+static int
1002+PerformAuthenticationTight(void)
1003+{
1004+ rfbAuthenticationCapsMsg caps;
1005+ CARD32 authScheme;
1006+ int i;
1007+
1008+ /* In the protocol version 3.7t, the server informs us about supported
1009+ authentication schemes. Here we read this infomation. */
1010+
1011+ if (!read_from_rfb_server(sock, (char *)&caps, sz_rfbAuthenticationCapsMsg)) return 0;
1012+
1013+ caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes);
1014+
1015+ if (!caps.nAuthTypes) {
1016+ fprintf(stderr, "No authentication needed\n");
1017+ return 1;
1018+ }
1019+
1020+ if (!ReadCapabilityList(authCaps, caps.nAuthTypes)) return 0;
1021+
1022+ /* Prefer Unix login authentication if a user name was given. */
1023+ if (opt.user && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) {
1024+ authScheme = Swap32IfLE(rfbAuthUnixLogin);
1025+ if (!write_exact(sock, (char *)&authScheme, sizeof(authScheme))) return 0;
1026+ return AuthenticateUnixLogin();
1027+ }
1028+
1029+ /* Otherwise, try server's preferred authentication scheme. */
1030+ for (i = 0; i < CapsNumEnabled(authCaps); i++) {
1031+ authScheme = CapsGetByOrder(authCaps, i);
1032+ if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC) continue; /* unknown scheme - cannot use it */
1033+ authScheme = Swap32IfLE(authScheme);
1034+ if (!write_exact(sock, (char *)&authScheme, sizeof(authScheme))) return 0;
1035+ authScheme = Swap32IfLE(authScheme); /* convert it back */
1036+
1037+ if (authScheme == rfbAuthUnixLogin) {
1038+ return AuthenticateUnixLogin();
1039+ } else if (authScheme == rfbAuthVNC) {
1040+ return AuthenticateVNC();
1041+ } else {
1042+ fprintf(stderr, "Should never happen\n");
1043+ /* Should never happen. */
1044+ return 0;
1045+ }
1046+ }
1047+
1048+ fprintf(stderr, "No suitable authentication schemes offered by server\n");
1049+ return 0;
1050+}
1051+
1052+/*
1053+ * In the protocol version 3.7t, the server informs us about supported
1054+ * protocol messages and encodings. Here we read this information.
1055+ */
1056+
1057+static int
1058+ReadInteractionCaps(void)
1059+{
1060+ rfbInteractionCapsMsg intr_caps;
1061+
1062+ /* Read the counts of list items following */
1063+ if (!read_from_rfb_server(sock, (char *)&intr_caps, sz_rfbInteractionCapsMsg))
1064+ return 0;
1065+ intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes);
1066+ intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes);
1067+ intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes);
1068+
1069+ /* Read the lists of server- and client-initiated messages */
1070+ return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) &&
1071+ ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) &&
1072+ ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes));
1073+}
1074+
1075+
1076 int
1077 _rfb_initialise_client()
1078 {
1079@@ -220,10 +592,166 @@
1080
1081 if (!read_from_rfb_server(sock, opt.server.name, len))
1082 return 0;
1083-
1084+ if (tightVncProtocol) {
1085+ /* Read interaction capabilities (protocol 3.7t) */
1086+ if (!ReadInteractionCaps())
1087+ return 0;
1088+ }
1089 return 1;
1090 }
1091
1092+/*
1093+ * SetFormatAndEncodings.
1094+ */
1095+
1096+int
1097+rfb_set_format_and_encodings()
1098+{
1099+ rfbSetPixelFormatMsg spf;
1100+ char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
1101+ rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
1102+ CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
1103+ int len = 0;
1104+ int requestCompressLevel = 0;
1105+ int requestQualityLevel = 0;
1106+ int requestLastRectEncoding = 0;
1107+
1108+ spf.type = 0;
1109+ spf.format.bitsPerPixel = opt.client.bpp;
1110+ spf.format.depth = opt.client.depth;
1111+ spf.format.bigEndian = opt.client.bigendian;
1112+ spf.format.trueColour = opt.client.truecolour;
1113+ spf.format.redMax = Swap16IfLE(opt.client.redmax);
1114+ spf.format.greenMax = Swap16IfLE(opt.client.greenmax);
1115+ spf.format.blueMax = Swap16IfLE(opt.client.bluemax);
1116+ spf.format.redShift =opt.client.redshift;
1117+ spf.format.greenShift = opt.client.greenshift;
1118+ spf.format.blueShift = opt.client.blueshift;
1119+
1120+ if (!write_exact(sock, (char *)&spf, sz_rfbSetPixelFormatMsg))
1121+ return 0;
1122+
1123+ se->type = rfbSetEncodings;
1124+ se->nEncodings = 0;
1125+
1126+ if (opt.encodings) {
1127+ char *encStr = opt.encodings;
1128+ int encStrLen;
1129+ do {
1130+ char *nextEncStr = strchr(encStr, ' ');
1131+ if (nextEncStr) {
1132+ encStrLen = nextEncStr - encStr;
1133+ nextEncStr++;
1134+ } else {
1135+ encStrLen = strlen(encStr);
1136+ }
1137+
1138+ if (strncasecmp(encStr,"raw",encStrLen) == 0) {
1139+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
1140+ } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
1141+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
1142+ } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
1143+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
1144+ requestLastRectEncoding = 1;
1145+ if (opt.client.compresslevel >= 0 && opt.client.compresslevel <= 9)
1146+ requestCompressLevel = 1;
1147+ requestQualityLevel = 1;
1148+ } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
1149+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
1150+ } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
1151+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
1152+ if (opt.client.compresslevel >= 0 && opt.client.compresslevel <= 9)
1153+ requestCompressLevel = 1;
1154+ } else if (strncasecmp(encStr,"corre",encStrLen) == 0) {
1155+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
1156+ } else if (strncasecmp(encStr,"rre",encStrLen) == 0) {
1157+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
1158+ } else {
1159+ fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
1160+ }
1161+
1162+ encStr = nextEncStr;
1163+ } while (encStr && se->nEncodings < MAX_ENCODINGS);
1164+
1165+ if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
1166+ encs[se->nEncodings++] = Swap32IfLE(opt.client.compresslevel +
1167+ rfbEncodingCompressLevel0);
1168+ }
1169+
1170+ if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
1171+ if (opt.client.quality < 0 || opt.client.quality > 9)
1172+ opt.client.quality = 5;
1173+ encs[se->nEncodings++] = Swap32IfLE(opt.client.quality +
1174+ rfbEncodingQualityLevel0);
1175+ }
1176+
1177+ if (opt.localcursor) {
1178+ if (se->nEncodings < MAX_ENCODINGS)
1179+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
1180+ if (se->nEncodings < MAX_ENCODINGS)
1181+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
1182+ if (se->nEncodings < MAX_ENCODINGS)
1183+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
1184+ }
1185+
1186+ if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
1187+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
1188+ }
1189+ } else {
1190+ if (SameMachine(sock)) {
1191+ if (!tunnelSpecified) {
1192+ fprintf(stderr,"Same machine: preferring raw encoding\n");
1193+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
1194+ } else {
1195+ fprintf(stderr,"Tunneling active: preferring tight encoding\n");
1196+ }
1197+ }
1198+
1199+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
1200+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
1201+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
1202+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
1203+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE);
1204+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE);
1205+
1206+ if (opt.client.compresslevel >= 0 && opt.client.compresslevel <= 9) {
1207+ encs[se->nEncodings++] = Swap32IfLE(opt.client.compresslevel +
1208+ rfbEncodingCompressLevel0);
1209+ } else if (!tunnelSpecified) {
1210+ /* If -tunnel option was provided, we assume that server machine is
1211+ not in the local network so we use default compression level for
1212+ tight encoding instead of fast compression. Thus we are
1213+ requesting level 1 compression only if tunneling is not used. */
1214+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCompressLevel1);
1215+ }
1216+#if 0
1217+ if (appData.enableJPEG) {
1218+ if (appData.qualityLevel < 0 || appData.qualityLevel > 9)
1219+ appData.qualityLevel = 5;
1220+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
1221+ rfbEncodingQualityLevel0);
1222+ }
1223+#endif
1224+
1225+ if (opt.localcursor) {
1226+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
1227+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
1228+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
1229+ }
1230+
1231+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
1232+ }
1233+
1234+ len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
1235+
1236+ se->nEncodings = Swap16IfLE(se->nEncodings);
1237+
1238+ if (!write_exact(sock, buf, len)) return 0;
1239+
1240+ return 1;
1241+}
1242+
1243+#if 0
1244 int
1245 rfb_set_format_and_encodings()
1246 {
1247@@ -312,7 +840,7 @@
1248
1249 return(1);
1250 }
1251-
1252+#endif
1253
1254 int
1255 rfb_send_update_request(int incremental)
1256@@ -347,84 +875,93 @@
1257 rfbFramebufferUpdateRectHeader rectheader;
1258
1259 if (!read_from_rfb_server(sock, (char*)&msg, 1)) return 0;
1260- switch (msg.type)
1261- {
1262- int i;
1263- case rfbFramebufferUpdate:
1264- read_from_rfb_server(sock, ((char*)&msg.fu)+1, sz_rfbFramebufferUpdateMsg-1);
1265- msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
1266- for (i=0;i< msg.fu.nRects;i++)
1267- {
1268- read_from_rfb_server(sock, (char*)&rectheader,
1269- sz_rfbFramebufferUpdateRectHeader);
1270- rectheader.r.x = Swap16IfLE(rectheader.r.x);
1271- rectheader.r.y = Swap16IfLE(rectheader.r.y);
1272- rectheader.r.w = Swap16IfLE(rectheader.r.w);
1273- rectheader.r.h = Swap16IfLE(rectheader.r.h);
1274- rectheader.encoding = Swap32IfLE(rectheader.encoding);
1275- SoftCursorLockArea(rectheader.r.x, rectheader.r.y, rectheader.r.w, rectheader.r.h);
1276- switch (rectheader.encoding)
1277- {
1278- case rfbEncodingRaw:
1279- _handle_raw_encoded_message(rectheader);
1280- break;
1281- case rfbEncodingCopyRect:
1282- _handle_copyrect_encoded_message(rectheader);
1283- break;
1284- case rfbEncodingRRE:
1285- _handle_rre_encoded_message(rectheader);
1286- break;
1287- case rfbEncodingCoRRE:
1288- _handle_corre_encoded_message(rectheader);
1289- break;
1290- case rfbEncodingHextile:
1291- _handle_hextile_encoded_message(rectheader);
1292- break;
1293- case rfbEncodingTight:
1294- _handle_tight_encoded_message(rectheader);
1295- break;
1296- case rfbEncodingZlib:
1297- _handle_zlib_encoded_message(rectheader);
1298- break;
1299- case rfbEncodingRichCursor:
1300- _handle_richcursor_message(rectheader);
1301- break;
1302+ switch (msg.type) {
1303+ int i;
1304+ case rfbFramebufferUpdate:
1305+ read_from_rfb_server(sock, ((char*)&msg.fu)+1, sz_rfbFramebufferUpdateMsg-1);
1306+ msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
1307+
1308+ for (i=0;i< msg.fu.nRects;i++) {
1309+ read_from_rfb_server(sock, (char*)&rectheader, sz_rfbFramebufferUpdateRectHeader);
1310+ rectheader.r.x = Swap16IfLE(rectheader.r.x);
1311+ rectheader.r.y = Swap16IfLE(rectheader.r.y);
1312+ rectheader.r.w = Swap16IfLE(rectheader.r.w);
1313+ rectheader.r.h = Swap16IfLE(rectheader.r.h);
1314+ rectheader.encoding = Swap32IfLE(rectheader.encoding);
1315+ if (rectheader.encoding == rfbEncodingLastRect) break;
1316+
1317+ if (rectheader.encoding == rfbEncodingPointerPos) {
1318+ if (!HandleCursorPos(rectheader.r.x, rectheader.r.y)) {
1319+ return 0;
1320+ }
1321+ continue;
1322+ }
1323+ SoftCursorLockArea(rectheader.r.x, rectheader.r.y, rectheader.r.w, rectheader.r.h);
1324+
1325+ switch (rectheader.encoding) {
1326+ case rfbEncodingRaw:
1327+ _handle_raw_encoded_message(rectheader);
1328+ break;
1329+ case rfbEncodingCopyRect:
1330+ _handle_copyrect_encoded_message(rectheader);
1331+ break;
1332+ case rfbEncodingRRE:
1333+ _handle_rre_encoded_message(rectheader);
1334+ break;
1335+ case rfbEncodingCoRRE:
1336+ _handle_corre_encoded_message(rectheader);
1337+ break;
1338+ case rfbEncodingHextile:
1339+ _handle_hextile_encoded_message(rectheader);
1340+ break;
1341+ case rfbEncodingTight:
1342+ _handle_tight_encoded_message(rectheader);
1343+ break;
1344+ case rfbEncodingZlib:
1345+ _handle_zlib_encoded_message(rectheader);
1346+ break;
1347+ case rfbEncodingRichCursor:
1348+ case rfbEncodingXCursor:
1349+ _handle_richcursor_message(rectheader);
1350+ break;
1351+#if 0
1352 case rfbEncodingLastRect:
1353- printf("LAST\n");
1354+ fprintf(stderr, "LAST\n");
1355 break;
1356-
1357- default:
1358- printf("Unknown encoding\n");
1359- return 0;
1360- break;
1361- }
1362- /* Now we may discard "soft cursor locks". */
1363- SoftCursorUnlockScreen();
1364+#endif
1365+ default:
1366+ fprintf(stderr, "Unknown encoding: %x\n", rectheader.encoding);
1367+ return 0;
1368+ break;
1369+ }
1370+ /* Now we may discard "soft cursor locks". */
1371+ SoftCursorUnlockScreen();
1372+ }
1373+ if (!rfb_send_update_request(1)) return 0;
1374
1375- }
1376- break;
1377- case rfbSetColourMapEntries:
1378- fprintf(stderr, "SetColourMapEntries\n");
1379- read_from_rfb_server(sock, ((char*)&msg.scme)+1, sz_rfbSetColourMapEntriesMsg-1);
1380- break;
1381- case rfbBell:
1382- fprintf(stderr, "Bell message. Unimplemented.\n");
1383- break;
1384- case rfbServerCutText:
1385- fprintf(stderr, "ServerCutText. Unimplemented.\n");
1386- read_from_rfb_server(sock, ((char*)&msg.sct)+1,
1387- sz_rfbServerCutTextMsg-1);
1388- size = Swap32IfLE(msg.sct.length);
1389- buf = malloc(sizeof(char) * size);
1390- read_from_rfb_server(sock, buf, size);
1391- buf[size]=0;
1392- printf("%s\n", buf);
1393- free(buf);
1394- break;
1395- default:
1396- printf("Unknown server message. Type: %i\n", msg.type);
1397- return 0;
1398- break;
1399+ break;
1400+
1401+ case rfbSetColourMapEntries:
1402+ fprintf(stderr, "SetColourMapEntries\n");
1403+ read_from_rfb_server(sock, ((char*)&msg.scme)+1, sz_rfbSetColourMapEntriesMsg-1);
1404+ break;
1405+ case rfbBell:
1406+ fprintf(stderr, "Bell message. Unimplemented.\n");
1407+ break;
1408+ case rfbServerCutText:
1409+ fprintf(stderr, "ServerCutText. Unimplemented.\n");
1410+ read_from_rfb_server(sock, ((char*)&msg.sct)+1, sz_rfbServerCutTextMsg-1);
1411+ size = Swap32IfLE(msg.sct.length);
1412+ buf = malloc(sizeof(char) * size);
1413+ read_from_rfb_server(sock, buf, size);
1414+ buf[size]=0;
1415+ printf("%s\n", buf);
1416+ free(buf);
1417+ break;
1418+ default:
1419+ printf("Unknown server message. Type: %i\n", msg.type);
1420+ return 0;
1421+ break;
1422 }
1423 return(1);
1424 }
1425@@ -688,7 +1225,7 @@
1426 static int
1427 _handle_richcursor_message(rfbFramebufferUpdateRectHeader rectheader)
1428 {
1429- return HandleRichCursor(rectheader.r.x, rectheader.r.y, rectheader.r.w, rectheader.r.h);
1430+ return HandleCursorShape(rectheader.r.x, rectheader.r.y, rectheader.r.w, rectheader.r.h, rectheader.encoding);
1431 }
1432
1433 void
1434diff -Nru directvnc-0.7.5/src/rfbproto.h directvnc-0.7.5.new/src/rfbproto.h
1435--- directvnc-0.7.5/src/rfbproto.h 2002-07-07 18:50:02.000000000 +0200
1436+++ directvnc-0.7.5.new/src/rfbproto.h 2007-01-15 16:42:12.000000000 +0100
1437@@ -1,3 +1,5 @@
1438+#ifndef VNC_RFBPROTO_H
1439+#define VNC_RFBPROTO_H
1440 /*
1441 * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved.
1442 * Copyright (C) 2000 Tridia Corporation. All Rights Reserved.
1443@@ -20,7 +22,7 @@
1444 */
1445
1446 /*
1447- * rfbproto.h - header file for the RFB protocol version 3.3
1448+ * rfbproto.h - header file for the RFB protocol version 3.7
1449 *
1450 * Uses types CARD<n> for an n-bit unsigned integer, INT<n> for an n-bit signed
1451 * integer (for n = 8, 16 and 32).
1452@@ -155,7 +157,8 @@
1453
1454 #define rfbProtocolVersionFormat "RFB %03d.%03d\n"
1455 #define rfbProtocolMajorVersion 3
1456-#define rfbProtocolMinorVersion 3
1457+#define rfbProtocolMinorVersion 7
1458+#define rfbProtocolFallbackMinorVersion 3
1459
1460 typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */
1461
1462@@ -163,6 +166,31 @@
1463
1464
1465 /*-----------------------------------------------------------------------------
1466+ * Structure used to describe protocol options such as tunneling methods,
1467+ * authentication schemes and message types (protocol version 3.7t).
1468+ */
1469+
1470+typedef struct _rfbCapabilityInfo {
1471+
1472+ CARD32 code; /* numeric identifier */
1473+ CARD8 vendorSignature[4]; /* vendor identification */
1474+ CARD8 nameSignature[8]; /* abbreviated option name */
1475+
1476+} rfbCapabilityInfo;
1477+
1478+#define sz_rfbCapabilityInfoVendor 4
1479+#define sz_rfbCapabilityInfoName 8
1480+#define sz_rfbCapabilityInfo 16
1481+
1482+/*
1483+ * Vendors known by TightVNC: standard VNC/RealVNC, TridiaVNC, and TightVNC.
1484+ */
1485+
1486+#define rfbStandardVendor "STDV"
1487+#define rfbTridiaVncVendor "TRDV"
1488+#define rfbTightVncVendor "TGHT"
1489+
1490+/*-----------------------------------------------------------------------------
1491 * Authentication
1492 *
1493 * Once the protocol version has been decided, the server then sends a 32-bit
1494@@ -174,6 +202,7 @@
1495 #define rfbConnFailed 0
1496 #define rfbNoAuth 1
1497 #define rfbVncAuth 2
1498+#define rfbSecTypeTight 16
1499
1500 /*
1501 * rfbConnFailed: For some reason the connection failed (e.g. the server
1502@@ -201,6 +230,160 @@
1503 #define rfbVncAuthFailed 1
1504 #define rfbVncAuthTooMany 2
1505
1506+/*-----------------------------------------------------------------------------
1507+ * Negotiation of Tunneling Capabilities (protocol version 3.7t)
1508+ *
1509+ * If the chosen security type is rfbSecTypeTight, the server sends a list of
1510+ * supported tunneling methods ("tunneling" refers to any additional layer of
1511+ * data transformation, such as encryption or external compression.)
1512+ *
1513+ * nTunnelTypes specifies the number of following rfbCapabilityInfo structures
1514+ * that list all supported tunneling methods in the order of preference.
1515+ *
1516+ * NOTE: If nTunnelTypes is 0, that tells the client that no tunneling can be
1517+ * used, and the client should not send a response requesting a tunneling
1518+ * method.
1519+ */
1520+
1521+typedef struct _rfbTunnelingCapsMsg {
1522+ CARD32 nTunnelTypes;
1523+ /* followed by nTunnelTypes * rfbCapabilityInfo structures */
1524+} rfbTunnelingCapsMsg;
1525+
1526+#define sz_rfbTunnelingCapsMsg 4
1527+
1528+/*-----------------------------------------------------------------------------
1529+ * Tunneling Method Request (protocol version 3.7t)
1530+ *
1531+ * If the list of tunneling capabilities sent by the server was not empty, the
1532+ * client should reply with a 32-bit code specifying a particular tunneling
1533+ * method. The following code should be used for no tunneling.
1534+ */
1535+
1536+#define rfbNoTunneling 0
1537+#define sig_rfbNoTunneling "NOTUNNEL"
1538+
1539+/*-----------------------------------------------------------------------------
1540+ * Negotiation of Authentication Capabilities (protocol version 3.7t)
1541+ *
1542+ * After setting up tunneling, the server sends a list of supported
1543+ * authentication schemes.
1544+ *
1545+ * nAuthTypes specifies the number of following rfbCapabilityInfo structures
1546+ * that list all supported authentication schemes in the order of preference.
1547+ *
1548+ * NOTE: If nAuthTypes is 0, that tells the client that no authentication is
1549+ * necessary, and the client should not send a response requesting an
1550+ * authentication scheme.
1551+ */
1552+
1553+typedef struct _rfbAuthenticationCapsMsg {
1554+ CARD32 nAuthTypes;
1555+ /* followed by nAuthTypes * rfbCapabilityInfo structures */
1556+} rfbAuthenticationCapsMsg;
1557+
1558+#define sz_rfbAuthenticationCapsMsg 4
1559+
1560+/*-----------------------------------------------------------------------------
1561+ * Authentication Scheme Request (protocol version 3.7t)
1562+ *
1563+ * If the list of authentication capabilities sent by the server was not empty,
1564+ * the client should reply with a 32-bit code specifying a particular
1565+ * authentication scheme. The following codes are supported.
1566+ */
1567+
1568+#define rfbAuthNone 1
1569+#define rfbAuthVNC 2
1570+#define rfbAuthUnixLogin 129
1571+#define rfbAuthExternal 130
1572+
1573+#define sig_rfbAuthNone "NOAUTH__"
1574+#define sig_rfbAuthVNC "VNCAUTH_"
1575+#define sig_rfbAuthUnixLogin "ULGNAUTH"
1576+#define sig_rfbAuthExternal "XTRNAUTH"
1577+
1578+/* signatures for basic encoding types */
1579+#define sig_rfbEncodingRaw "RAW_____"
1580+#define sig_rfbEncodingCopyRect "COPYRECT"
1581+#define sig_rfbEncodingRRE "RRE_____"
1582+#define sig_rfbEncodingCoRRE "CORRE___"
1583+#define sig_rfbEncodingHextile "HEXTILE_"
1584+#define sig_rfbEncodingZlib "ZLIB____"
1585+#define sig_rfbEncodingTight "TIGHT___"
1586+#define sig_rfbEncodingZlibHex "ZLIBHEX_"
1587+
1588+/*
1589+ * Special encoding numbers:
1590+ * 0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels;
1591+ * 0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data;
1592+ * 0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions;
1593+ * 0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet;
1594+ * 0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor;
1595+ * 0xFFFFFFF0 .. 0xFFFFFFFF -- not allocated yet.
1596+ */
1597+
1598+#define rfbEncodingCompressLevel0 0xFFFFFF00
1599+#define rfbEncodingCompressLevel1 0xFFFFFF01
1600+#define rfbEncodingCompressLevel2 0xFFFFFF02
1601+#define rfbEncodingCompressLevel3 0xFFFFFF03
1602+#define rfbEncodingCompressLevel4 0xFFFFFF04
1603+#define rfbEncodingCompressLevel5 0xFFFFFF05
1604+#define rfbEncodingCompressLevel6 0xFFFFFF06
1605+#define rfbEncodingCompressLevel7 0xFFFFFF07
1606+#define rfbEncodingCompressLevel8 0xFFFFFF08
1607+#define rfbEncodingCompressLevel9 0xFFFFFF09
1608+
1609+#define rfbEncodingXCursor 0xFFFFFF10
1610+#define rfbEncodingRichCursor 0xFFFFFF11
1611+#define rfbEncodingPointerPos 0xFFFFFF18
1612+
1613+#define rfbEncodingLastRect 0xFFFFFF20
1614+#define rfbEncodingNewFBSize 0xFFFFFF21
1615+
1616+#define rfbEncodingQualityLevel0 0xFFFFFFE0
1617+#define rfbEncodingQualityLevel1 0xFFFFFFE1
1618+#define rfbEncodingQualityLevel2 0xFFFFFFE2
1619+#define rfbEncodingQualityLevel3 0xFFFFFFE3
1620+#define rfbEncodingQualityLevel4 0xFFFFFFE4
1621+#define rfbEncodingQualityLevel5 0xFFFFFFE5
1622+#define rfbEncodingQualityLevel6 0xFFFFFFE6
1623+#define rfbEncodingQualityLevel7 0xFFFFFFE7
1624+#define rfbEncodingQualityLevel8 0xFFFFFFE8
1625+#define rfbEncodingQualityLevel9 0xFFFFFFE9
1626+
1627+/* signatures for "fake" encoding types */
1628+#define sig_rfbEncodingCompressLevel0 "COMPRLVL"
1629+#define sig_rfbEncodingXCursor "X11CURSR"
1630+#define sig_rfbEncodingRichCursor "RCHCURSR"
1631+#define sig_rfbEncodingPointerPos "POINTPOS"
1632+#define sig_rfbEncodingLastRect "LASTRECT"
1633+#define sig_rfbEncodingNewFBSize "NEWFBSIZ"
1634+#define sig_rfbEncodingQualityLevel0 "JPEGQLVL"
1635+
1636+/*-----------------------------------------------------------------------------
1637+ * Server Interaction Capabilities Message (protocol version 3.7t)
1638+ *
1639+ * In the protocol version 3.7t, the server informs the client what message
1640+ * types it supports in addition to ones defined in the protocol version 3.7.
1641+ * Also, the server sends the list of all supported encodings (note that it's
1642+ * not necessary to advertise the "raw" encoding sinse it MUST be supported in
1643+ * RFB 3.x protocols).
1644+ *
1645+ * This data immediately follows the server initialisation message.
1646+ */
1647+
1648+typedef struct _rfbInteractionCapsMsg {
1649+ CARD16 nServerMessageTypes;
1650+ CARD16 nClientMessageTypes;
1651+ CARD16 nEncodingTypes;
1652+ CARD16 pad; /* reserved, must be 0 */
1653+ /* followed by nServerMessageTypes * rfbCapabilityInfo structures */
1654+ /* followed by nClientMessageTypes * rfbCapabilityInfo structures */
1655+} rfbInteractionCapsMsg;
1656+
1657+#define sz_rfbInteractionCapsMsg 8
1658+
1659+
1660
1661 /*-----------------------------------------------------------------------------
1662 * Client Initialisation Message
1663@@ -783,3 +966,5 @@
1664 rfbPointerEventMsg pe;
1665 rfbClientCutTextMsg cct;
1666 } rfbClientToServerMsg;
1667+
1668+#endif /* VNC_RFBPROTO_H */
1669diff -Nru directvnc-0.7.5/src/sockets.c directvnc-0.7.5.new/src/sockets.c
1670--- directvnc-0.7.5/src/sockets.c 2003-01-31 08:33:02.000000000 +0100
1671+++ directvnc-0.7.5.new/src/sockets.c 2007-01-15 17:22:15.000000000 +0100
1672@@ -273,3 +273,19 @@
1673
1674 fflush(stderr);
1675 }
1676+
1677+/*
1678+ * Test if the other end of a socket is on the same machine.
1679+ */
1680+
1681+int
1682+SameMachine(int sock)
1683+{
1684+ struct sockaddr_in peeraddr, myaddr;
1685+ int addrlen = sizeof(struct sockaddr_in);
1686+
1687+ getpeername(sock, (struct sockaddr *)&peeraddr, &addrlen);
1688+ getsockname(sock, (struct sockaddr *)&myaddr, &addrlen);
1689+
1690+ return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr);
1691+}
This page took 0.391496 seconds and 4 git commands to generate.