@@ -37,18 +37,17 @@ void rfbClientSendString(rfbClientPtr cl, const char *reason);
37
37
* Handle security types
38
38
*/
39
39
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. */
40
44
static rfbSecurityHandler * securityHandlers = NULL ;
41
45
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
- */
48
46
void
49
- rfbRegisterSecurityHandler (rfbSecurityHandler * handler )
47
+ rfbRegisterSecurityHandlerTo (rfbSecurityHandler * handler ,
48
+ rfbSecurityHandler * * handlerList )
50
49
{
51
- rfbSecurityHandler * head = securityHandlers , * next = NULL ;
50
+ rfbSecurityHandler * head = * handlerList , * next = NULL ;
52
51
53
52
if (handler == NULL )
54
53
return ;
@@ -57,39 +56,35 @@ rfbRegisterSecurityHandler(rfbSecurityHandler* handler)
57
56
58
57
while (head != NULL ) {
59
58
if (head == handler ) {
60
- rfbRegisterSecurityHandler (next );
59
+ rfbRegisterSecurityHandlerTo (next , handlerList );
61
60
return ;
62
61
}
63
62
64
63
head = head -> next ;
65
64
}
66
65
67
- handler -> next = securityHandlers ;
68
- securityHandlers = handler ;
66
+ handler -> next = * handlerList ;
67
+ * handlerList = handler ;
69
68
70
- rfbRegisterSecurityHandler (next );
69
+ rfbRegisterSecurityHandlerTo (next , handlerList );
71
70
}
72
71
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 )
80
75
{
81
76
rfbSecurityHandler * cur = NULL , * pre = NULL ;
82
77
83
78
if (handler == NULL )
84
79
return ;
85
80
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 );
89
84
return ;
90
85
}
91
86
92
- cur = pre = securityHandlers ;
87
+ cur = pre = * handlerList ;
93
88
94
89
while (cur ) {
95
90
if (cur == handler ) {
@@ -99,7 +94,50 @@ rfbUnregisterSecurityHandler(rfbSecurityHandler* handler)
99
94
pre = cur ;
100
95
cur = cur -> next ;
101
96
}
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 );
103
141
}
104
142
105
143
/*
@@ -197,19 +235,33 @@ static rfbSecurityHandler VncSecurityHandlerNone = {
197
235
NULL
198
236
};
199
237
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
+ }
200
250
201
- static void
202
- rfbSendSecurityTypeList (rfbClientPtr cl , int primaryType )
251
+ void
252
+ rfbSendSecurityTypeList (rfbClientPtr cl ,
253
+ enum rfbSecurityTag exclude )
203
254
{
204
255
/* The size of the message is the count of security types +1,
205
256
* since the first byte is the number of types. */
206
257
int size = 1 ;
207
258
rfbSecurityHandler * handler ;
208
259
#define MAX_SECURITY_TYPES 255
209
260
uint8_t buffer [MAX_SECURITY_TYPES + 1 ];
210
-
261
+ int32_t primaryType ;
211
262
212
263
/* Fill in the list of security types in the client structure. (NOTE: Not really in the client structure) */
264
+ primaryType = determinePrimarySecurityType (cl );
213
265
switch (primaryType ) {
214
266
case rfbSecTypeNone :
215
267
rfbRegisterSecurityHandler (& VncSecurityHandlerNone );
@@ -221,6 +273,9 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
221
273
222
274
for (handler = securityHandlers ;
223
275
handler && size < MAX_SECURITY_TYPES ; handler = handler -> next ) {
276
+ if (exclude && (handler -> securityTags & exclude ))
277
+ continue ;
278
+
224
279
buffer [size ] = handler -> type ;
225
280
size ++ ;
226
281
}
@@ -249,7 +304,29 @@ rfbSendSecurityTypeList(rfbClientPtr cl, int primaryType)
249
304
cl -> state = RFB_SECURITY_TYPE ;
250
305
}
251
306
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
+ }
252
326
327
+ /* Dispatch client input to rfbProcessClientChannelSecurityType. */
328
+ cl -> state = RFB_CHANNEL_SECURITY_TYPE ;
329
+ }
253
330
254
331
255
332
/*
@@ -297,28 +374,33 @@ rfbSendSecurityType(rfbClientPtr cl, int32_t securityType)
297
374
void
298
375
rfbAuthNewClient (rfbClientPtr cl )
299
376
{
300
- int32_t securityType = rfbSecTypeInvalid ;
377
+ int32_t securityType ;
301
378
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 );
308
380
309
381
if (cl -> protocolMajorVersion == 3 && cl -> protocolMinorVersion < 7 )
310
382
{
311
383
/* 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
+ }
312
390
if (securityType == rfbSecTypeInvalid ) {
313
391
rfbLog ("VNC authentication disabled - RFB 3.3 client rejected\n" );
314
392
rfbClientConnFailed (cl , "Your viewer cannot handle required "
315
393
"authentication methods" );
316
394
return ;
317
395
}
318
396
rfbSendSecurityType (cl , securityType );
397
+ } else if (channelSecurityHandlers ) {
398
+ rfbLog ("Send channel security type list\n" );
399
+ rfbSendChannelSecurityTypeList (cl );
319
400
} else {
320
401
/* 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 );
322
404
}
323
405
}
324
406
@@ -332,6 +414,7 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
332
414
int n ;
333
415
uint8_t chosenType ;
334
416
rfbSecurityHandler * handler ;
417
+ rfbSecurityHandler * handlerListHead ;
335
418
336
419
/* Read the security type. */
337
420
n = rfbReadExact (cl , (char * )& chosenType , 1 );
@@ -344,8 +427,17 @@ rfbProcessClientSecurityType(rfbClientPtr cl)
344
427
return ;
345
428
}
346
429
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
+
347
439
/* 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 ) {
349
441
if (chosenType == handler -> type ) {
350
442
rfbLog ("rfbProcessClientSecurityType: executing handler for type %d\n" , chosenType );
351
443
handler -> handler (cl );
0 commit comments