@@ -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 rfbUnregisterSecurityHandler (& VncSecurityHandlerVncAuth );
@@ -223,6 +275,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
223275
224276 for (handler = securityHandlers ;
225277 handler && size < MAX_SECURITY_TYPES ; handler = handler -> next ) {
278+ if (exclude && (handler -> securityTags & exclude ))
279+ continue ;
280+
226281 buffer [size ] = handler -> type ;
227282 size ++ ;
228283 }
@@ -251,7 +306,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
251306 cl -> state = RFB_SECURITY_TYPE ;
252307}
253308
309+ static void
310+ rfbSendChannelSecurityTypeList (rfbClientPtr cl )
311+ {
312+ int size = 1 ;
313+ rfbSecurityHandler * handler ;
314+ uint8_t buffer [MAX_SECURITY_TYPES + 1 ];
315+
316+ for (handler = channelSecurityHandlers ;
317+ handler && size < MAX_SECURITY_TYPES ; handler = handler -> next ) {
318+ buffer [size ] = handler -> type ;
319+ size ++ ;
320+ }
321+ buffer [0 ] = (unsigned char )size - 1 ;
322+
323+ if (rfbWriteExact (cl , (char * )buffer , size ) < 0 ) {
324+ rfbLogPerror ("rfbSendSecurityTypeList: write" );
325+ rfbCloseClient (cl );
326+ return ;
327+ }
254328
329+ /* Dispatch client input to rfbProcessClientChannelSecurityType. */
330+ cl -> state = RFB_CHANNEL_SECURITY_TYPE ;
331+ }
255332
256333
257334/*
@@ -299,28 +376,33 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
299376void
300377rfbAuthNewClient (rfbClientPtr cl )
301378{
302- int32_t securityType = rfbSecTypeInvalid ;
379+ int32_t securityType ;
303380
304- if (!cl -> screen -> authPasswdData || cl -> reverseConnection ) {
305- /* chk if this condition is valid or not. */
306- securityType = rfbSecTypeNone ;
307- } else if (cl -> screen -> authPasswdData ) {
308- securityType = rfbSecTypeVncAuth ;
309- }
381+ securityType = determinePrimarySecurityType (cl );
310382
311383 if (cl -> protocolMajorVersion == 3 && cl -> protocolMinorVersion < 7 )
312384 {
313385 /* Make sure we use only RFB 3.3 compatible security types. */
386+ if (channelSecurityHandlers ) {
387+ rfbLog ("VNC channel security enabled - RFB 3.3 client rejected\n" );
388+ rfbClientConnFailed (cl , "Your viewer cannot handler required "
389+ "security methods" );
390+ return ;
391+ }
314392 if (securityType == rfbSecTypeInvalid ) {
315393 rfbLog ("VNC authentication disabled - RFB 3.3 client rejected\n" );
316394 rfbClientConnFailed (cl , "Your viewer cannot handle required "
317395 "authentication methods" );
318396 return ;
319397 }
320398 rfbSendSecurityType (cl , securityType );
399+ } else if (channelSecurityHandlers ) {
400+ rfbLog ("Send channel security type list\n" );
401+ rfbSendChannelSecurityTypeList (cl );
321402 } else {
322403 /* Here it's ok when securityType is set to rfbSecTypeInvalid. */
323- rfbSendSecurityTypeList (cl , securityType );
404+ rfbLog ("Send channel security type 'none'\n" );
405+ rfbSendSecurityTypeList (cl , RFB_SECURITY_TAG_NONE );
324406 }
325407}
326408
@@ -334,6 +416,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
334416 int n ;
335417 uint8_t chosenType ;
336418 rfbSecurityHandler * handler ;
419+ rfbSecurityHandler * handlerListHead ;
337420
338421 /* Read the security type. */
339422 n = rfbReadExact (cl , (char * )& chosenType , 1 );
@@ -346,8 +429,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
346429 return ;
347430 }
348431
432+ switch (cl -> state ) {
433+ case RFB_CHANNEL_SECURITY_TYPE :
434+ handlerListHead = channelSecurityHandlers ;
435+ break ;
436+ case RFB_SECURITY_TYPE :
437+ handlerListHead = securityHandlers ;
438+ break ;
439+ }
440+
349441 /* Make sure it was present in the list sent by the server. */
350- for (handler = securityHandlers ; handler ; handler = handler -> next ) {
442+ for (handler = handlerListHead ; handler ; handler = handler -> next ) {
351443 if (chosenType == handler -> type ) {
352444 rfbLog ("rfbProcessClientSecurityType: executing handler for type %d\n" , chosenType );
353445 handler -> handler (cl );
0 commit comments