@@ -37,18 +37,17 @@ void rfbClientSendString(rfbClientPtr cl, const char *reason);
3737 * Handle security types
3838 */
3939
40+ /* Channel security handlers to set up a secure channel, e.g. TLS. */
41+ static rfbSecurityHandler * channelSecurityHandlers = NULL ;
42+
43+ /* Security handlers when channel security is established. */
4044static rfbSecurityHandler * securityHandlers = NULL ;
4145
42- /*
43- * This method registers a list of new security types.
44- * It avoids same security type getting registered multiple times.
45- * The order is not preserved if multiple security types are
46- * registered at one-go.
47- */
4846void
49- rfbRegisterSecurityHandler (rfbSecurityHandler * handler )
47+ rfbRegisterSecurityHandlerTo (rfbSecurityHandler * handler ,
48+ rfbSecurityHandler * * handlerList )
5049{
51- rfbSecurityHandler * head = securityHandlers , * next = NULL ;
50+ rfbSecurityHandler * head = * handlerList , * next = NULL ;
5251
5352 if (handler == NULL )
5453 return ;
@@ -57,39 +56,35 @@ rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
5756
5857 while (head != NULL ) {
5958 if (head == handler ) {
60- rfbRegisterSecurityHandler (next );
59+ rfbRegisterSecurityHandlerTo (next , handlerList );
6160 return ;
6261 }
6362
6463 head = head -> next ;
6564 }
6665
67- handler -> next = securityHandlers ;
68- securityHandlers = handler ;
66+ handler -> next = * handlerList ;
67+ * handlerList = handler ;
6968
70- rfbRegisterSecurityHandler (next );
69+ rfbRegisterSecurityHandlerTo (next , handlerList );
7170}
7271
73- /*
74- * This method unregisters a list of security types.
75- * These security types won't be available for any new
76- * client connection.
77- */
78- void
79- rfbUnregisterSecurityHandler (rfbSecurityHandler * handler )
72+ static void
73+ rfbUnregisterSecurityHandlerFrom (rfbSecurityHandler * handler ,
74+ rfbSecurityHandler * * handlerList )
8075{
8176 rfbSecurityHandler * cur = NULL , * pre = NULL ;
8277
8378 if (handler == NULL )
8479 return ;
8580
86- if (securityHandlers == handler ) {
87- securityHandlers = securityHandlers -> next ;
88- rfbUnregisterSecurityHandler (handler -> next );
81+ if (* handlerList == handler ) {
82+ * handlerList = ( * handlerList ) -> next ;
83+ rfbUnregisterSecurityHandlerFrom (handler -> next , handlerList );
8984 return ;
9085 }
9186
92- cur = pre = securityHandlers ;
87+ cur = pre = * handlerList ;
9388
9489 while (cur ) {
9590 if (cur == handler ) {
@@ -99,7 +94,50 @@ rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
9994 pre = cur ;
10095 cur = cur -> next ;
10196 }
102- rfbUnregisterSecurityHandler (handler -> next );
97+ rfbUnregisterSecurityHandlerFrom (handler -> next , handlerList );
98+ }
99+
100+ void
101+ rfbRegisterChannelSecurityHandler (rfbSecurityHandler * handler )
102+ {
103+ rfbRegisterSecurityHandlerTo (handler , & channelSecurityHandlers );
104+ }
105+
106+ /*
107+ * This method unregisters a list of security types.
108+ * These security types won't be available for any new
109+ * client connection.
110+ */
111+
112+ void
113+ rfbUnregisterChannelSecurityHandler (rfbSecurityHandler * handler )
114+ {
115+ rfbUnregisterSecurityHandlerFrom (handler , & channelSecurityHandlers );
116+ }
117+
118+ /*
119+ * This method registers a list of new security types.
120+ * It avoids same security type getting registered multiple times.
121+ * The order is not preserved if multiple security types are
122+ * registered at one-go.
123+ */
124+
125+ void
126+ rfbRegisterSecurityHandler (rfbSecurityHandler * handler )
127+ {
128+ rfbRegisterSecurityHandlerTo (handler , & securityHandlers );
129+ }
130+
131+ /*
132+ * This method unregisters a list of security types.
133+ * These security types won't be available for any new
134+ * client connection.
135+ */
136+
137+ void
138+ rfbUnregisterSecurityHandler (rfbSecurityHandler * handler )
139+ {
140+ rfbUnregisterSecurityHandlerFrom (handler , & securityHandlers );
103141}
104142
105143/*
@@ -197,19 +235,33 @@ static rfbSecurityHandler VncSecurityHandlerNone = {
197235 NULL
198236};
199237
238+ static int32_t
239+ determinePrimarySecurityType (rfbClientPtr cl )
240+ {
241+ if (!cl -> screen -> authPasswdData || cl -> reverseConnection ) {
242+ /* chk if this condition is valid or not. */
243+ return rfbSecTypeNone ;
244+ } else if (cl -> screen -> authPasswdData ) {
245+ return rfbSecTypeVncAuth ;
246+ } else {
247+ return rfbSecTypeInvalid ;
248+ }
249+ }
200250
201- static void
202- rfbSendSecurityTypeList (rfbClientPtr cl , int primaryType )
251+ void
252+ rfbSendSecurityTypeList (rfbClientPtr cl ,
253+ enum rfbSecurityTag exclude )
203254{
204255 /* The size of the message is the count of security types +1,
205256 * since the first byte is the number of types. */
206257 int size = 1 ;
207258 rfbSecurityHandler * handler ;
208259#define MAX_SECURITY_TYPES 255
209260 uint8_t buffer [MAX_SECURITY_TYPES + 1 ];
210-
261+ int32_t primaryType ;
211262
212263 /* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
264+ primaryType = determinePrimarySecurityType (cl );
213265 switch (primaryType ) {
214266 case rfbSecTypeNone :
215267 rfbRegisterSecurityHandler (& VncSecurityHandlerNone );
@@ -221,6 +273,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
221273
222274 for (handler = securityHandlers ;
223275 handler && size < MAX_SECURITY_TYPES ; handler = handler -> next ) {
276+ if (exclude && (handler -> securityTags & exclude ))
277+ continue ;
278+
224279 buffer [size ] = handler -> type ;
225280 size ++ ;
226281 }
@@ -249,7 +304,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
249304 cl -> state = RFB_SECURITY_TYPE ;
250305}
251306
307+ static void
308+ rfbSendChannelSecurityTypeList (rfbClientPtr cl )
309+ {
310+ int size = 1 ;
311+ rfbSecurityHandler * handler ;
312+ uint8_t buffer [MAX_SECURITY_TYPES + 1 ];
313+
314+ for (handler = channelSecurityHandlers ;
315+ handler && size < MAX_SECURITY_TYPES ; handler = handler -> next ) {
316+ buffer [size ] = handler -> type ;
317+ size ++ ;
318+ }
319+ buffer [0 ] = (unsigned char )size - 1 ;
320+
321+ if (rfbWriteExact (cl , (char * )buffer , size ) < 0 ) {
322+ rfbLogPerror ("rfbSendSecurityTypeList: write" );
323+ rfbCloseClient (cl );
324+ return ;
325+ }
252326
327+ /* Dispatch client input to rfbProcessClientChannelSecurityType. */
328+ cl -> state = RFB_CHANNEL_SECURITY_TYPE ;
329+ }
253330
254331
255332/*
@@ -297,28 +374,33 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
297374void
298375rfbAuthNewClient (rfbClientPtr cl )
299376{
300- int32_t securityType = rfbSecTypeInvalid ;
377+ int32_t securityType ;
301378
302- if (!cl -> screen -> authPasswdData || cl -> reverseConnection ) {
303- /* chk if this condition is valid or not. */
304- securityType = rfbSecTypeNone ;
305- } else if (cl -> screen -> authPasswdData ) {
306- securityType = rfbSecTypeVncAuth ;
307- }
379+ securityType = determinePrimarySecurityType (cl );
308380
309381 if (cl -> protocolMajorVersion == 3 && cl -> protocolMinorVersion < 7 )
310382 {
311383 /* Make sure we use only RFB 3.3 compatible security types. */
384+ if (channelSecurityHandlers ) {
385+ rfbLog ("VNC channel security enabled - RFB 3.3 client rejected\n" );
386+ rfbClientConnFailed (cl , "Your viewer cannot hnadler required "
387+ "security methods" );
388+ return ;
389+ }
312390 if (securityType == rfbSecTypeInvalid ) {
313391 rfbLog ("VNC authentication disabled - RFB 3.3 client rejected\n" );
314392 rfbClientConnFailed (cl , "Your viewer cannot handle required "
315393 "authentication methods" );
316394 return ;
317395 }
318396 rfbSendSecurityType (cl , securityType );
397+ } else if (channelSecurityHandlers ) {
398+ rfbLog ("Send channel security type list\n" );
399+ rfbSendChannelSecurityTypeList (cl );
319400 } else {
320401 /* Here it's ok when securityType is set to rfbSecTypeInvalid. */
321- rfbSendSecurityTypeList (cl , securityType );
402+ rfbLog ("Send channel security type 'none'\n" );
403+ rfbSendSecurityTypeList (cl , RFB_SECURITY_TAG_NONE );
322404 }
323405}
324406
@@ -332,6 +414,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
332414 int n ;
333415 uint8_t chosenType ;
334416 rfbSecurityHandler * handler ;
417+ rfbSecurityHandler * handlerListHead ;
335418
336419 /* Read the security type. */
337420 n = rfbReadExact (cl , (char * )& chosenType , 1 );
@@ -344,8 +427,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
344427 return ;
345428 }
346429
430+ switch (cl -> state ) {
431+ case RFB_CHANNEL_SECURITY_TYPE :
432+ handlerListHead = channelSecurityHandlers ;
433+ break ;
434+ case RFB_SECURITY_TYPE :
435+ handlerListHead = securityHandlers ;
436+ break ;
437+ }
438+
347439 /* Make sure it was present in the list sent by the server. */
348- for (handler = securityHandlers ; handler ; handler = handler -> next ) {
440+ for (handler = handlerListHead ; handler ; handler = handler -> next ) {
349441 if (chosenType == handler -> type ) {
350442 rfbLog ("rfbProcessClientSecurityType: executing handler for type %d\n" , chosenType );
351443 handler -> handler (cl );
0 commit comments