1 /*
2 * Copyright (C) 2012 Philip Van Hoof <philip@codeminded.be>
3 * Copyright (C) 2009 Vic Lee.
4 *
5 * This is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This software is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18 * USA.
19 */
20
21 #include <rfb/rfbclient.h>
22 #include <errno.h>
23
24 #include <openssl/err.h>
25 #include <openssl/ssl.h>
26 #include <openssl/x509.h>
27 #include <openssl/rand.h>
28 #include <openssl/x509.h>
29
30 #ifdef _MSC_VER
31 typedef CRITICAL_SECTION MUTEX_TYPE;
32 #define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex)
33 #define MUTEX_FREE(mutex) DeleteCriticalSection(&mutex)
34 #define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex)
35 #define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex)
36 #define CURRENT_THREAD_ID GetCurrentThreadId()
37 #else
38 typedef pthread_mutex_t MUTEX_TYPE;
39 #define MUTEX_INIT(mutex) {\
40 pthread_mutexattr_t mutexAttr;\
41 pthread_mutexattr_init(&mutexAttr);\
42 pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\
43 pthread_mutex_init(&mutex, &mutexAttr);\
44 }
45 #define MUTEX_FREE(mutex) pthread_mutex_destroy(&mutex)
46 #define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex)
47 #define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex)
48 #define CURRENT_THREAD_ID pthread_self()
49 #endif
50
51 #ifndef _MSC_VER
52 #include <pthread.h>
53 #endif
54
55 #include "tls.h"
56
57 #ifdef _MSC_VER
58 #include <BaseTsd.h> // That's for SSIZE_T
59 typedef SSIZE_T ssize_t;
60 #define snprintf _snprintf
61 #endif
62
63 static rfbBool rfbTLSInitialized = FALSE;
64 static MUTEX_TYPE *mutex_buf = NULL;
65
66 struct CRYPTO_dynlock_value {
67 MUTEX_TYPE mutex;
68 };
69
locking_function(int mode,int n,const char * file,int line)70 static void locking_function(int mode, int n, const char *file, int line)
71 {
72 if (mode & CRYPTO_LOCK)
73 MUTEX_LOCK(mutex_buf[n]);
74 else
75 MUTEX_UNLOCK(mutex_buf[n]);
76 }
77
id_function(void)78 static unsigned long id_function(void)
79 {
80 return ((unsigned long) CURRENT_THREAD_ID);
81 }
82
dyn_create_function(const char * file,int line)83 static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
84 {
85 struct CRYPTO_dynlock_value *value;
86
87 value = (struct CRYPTO_dynlock_value *)
88 malloc(sizeof(struct CRYPTO_dynlock_value));
89 if (!value)
90 goto err;
91 MUTEX_INIT(value->mutex);
92
93 return value;
94
95 err:
96 return (NULL);
97 }
98
dyn_lock_function(int mode,struct CRYPTO_dynlock_value * l,const char * file,int line)99 static void dyn_lock_function (int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
100 {
101 if (mode & CRYPTO_LOCK)
102 MUTEX_LOCK(l->mutex);
103 else
104 MUTEX_UNLOCK(l->mutex);
105 }
106
107
108 static void
dyn_destroy_function(struct CRYPTO_dynlock_value * l,const char * file,int line)109 dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
110 {
111 MUTEX_FREE(l->mutex);
112 free(l);
113 }
114
115
116 static int
ssl_errno(SSL * ssl,int ret)117 ssl_errno (SSL *ssl, int ret)
118 {
119 switch (SSL_get_error (ssl, ret)) {
120 case SSL_ERROR_NONE:
121 return 0;
122 case SSL_ERROR_ZERO_RETURN:
123 /* this one does not map well at all */
124 //d(printf ("ssl_errno: SSL_ERROR_ZERO_RETURN\n"));
125 return EINVAL;
126 case SSL_ERROR_WANT_READ: /* non-fatal; retry */
127 case SSL_ERROR_WANT_WRITE: /* non-fatal; retry */
128 //d(printf ("ssl_errno: SSL_ERROR_WANT_[READ,WRITE]\n"));
129 return EAGAIN;
130 case SSL_ERROR_SYSCALL:
131 //d(printf ("ssl_errno: SSL_ERROR_SYSCALL\n"));
132 return EINTR;
133 case SSL_ERROR_SSL:
134 //d(printf ("ssl_errno: SSL_ERROR_SSL <-- very useful error...riiiiight\n"));
135 return EINTR;
136 default:
137 //d(printf ("ssl_errno: default error\n"));
138 return EINTR;
139 }
140 }
141
142 static rfbBool
InitializeTLS(void)143 InitializeTLS(void)
144 {
145 int i;
146
147 if (rfbTLSInitialized) return TRUE;
148
149 mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
150 if (mutex_buf == NULL) {
151 rfbClientLog("Failed to initialized OpenSSL: memory.\n");
152 return (-1);
153 }
154
155 for (i = 0; i < CRYPTO_num_locks(); i++)
156 MUTEX_INIT(mutex_buf[i]);
157
158 CRYPTO_set_locking_callback(locking_function);
159 CRYPTO_set_id_callback(id_function);
160 CRYPTO_set_dynlock_create_callback(dyn_create_function);
161 CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
162 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
163 SSL_load_error_strings();
164 SSLeay_add_ssl_algorithms();
165 RAND_load_file("/dev/urandom", 1024);
166
167 rfbClientLog("OpenSSL initialized.\n");
168 rfbTLSInitialized = TRUE;
169 return TRUE;
170 }
171
172 static int
ssl_verify(int ok,X509_STORE_CTX * ctx)173 ssl_verify (int ok, X509_STORE_CTX *ctx)
174 {
175 unsigned char md5sum[16], fingerprint[40], *f;
176 rfbClient *client;
177 int err, i;
178 unsigned int md5len;
179 //char buf[257];
180 X509 *cert;
181 SSL *ssl;
182
183 if (ok)
184 return TRUE;
185
186 ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx ());
187
188 client = SSL_CTX_get_app_data (ssl->ctx);
189
190 cert = X509_STORE_CTX_get_current_cert (ctx);
191 err = X509_STORE_CTX_get_error (ctx);
192
193 /* calculate the MD5 hash of the raw certificate */
194 md5len = sizeof (md5sum);
195 X509_digest (cert, EVP_md5 (), md5sum, &md5len);
196 for (i = 0, f = fingerprint; i < 16; i++, f += 3)
197 sprintf ((char *) f, "%.2x%c", md5sum[i], i != 15 ? ':' : '\0');
198
199 #define GET_STRING(name) X509_NAME_oneline (name, buf, 256)
200
201 /* TODO: Don't just ignore certificate checks
202
203 fingerprint = key to check in db
204
205 GET_STRING (X509_get_issuer_name (cert));
206 GET_STRING (X509_get_subject_name (cert));
207 cert->valid (bool: GOOD or BAD) */
208
209 ok = TRUE;
210
211 return ok;
212 }
213
sock_read_ready(SSL * ssl,uint32_t ms)214 static int sock_read_ready(SSL *ssl, uint32_t ms)
215 {
216 int r = 0;
217 fd_set fds;
218 struct timeval tv;
219
220 FD_ZERO(&fds);
221
222 FD_SET(SSL_get_fd(ssl), &fds);
223
224 tv.tv_sec = ms / 1000;
225 tv.tv_usec = (ms % 1000) * 1000;
226
227 r = select (SSL_get_fd(ssl) + 1, &fds, NULL, NULL, &tv);
228
229 return r;
230 }
231
wait_for_data(SSL * ssl,int ret,int timeout)232 static int wait_for_data(SSL *ssl, int ret, int timeout)
233 {
234 int err;
235 int retval = 1;
236
237 err = SSL_get_error(ssl, ret);
238
239 switch(err)
240 {
241 case SSL_ERROR_WANT_READ:
242 case SSL_ERROR_WANT_WRITE:
243 ret = sock_read_ready(ssl, timeout*1000);
244
245 if (ret == -1) {
246 retval = 2;
247 }
248
249 break;
250 default:
251 retval = 3;
252 break;
253 }
254
255 ERR_clear_error();
256
257 return retval;
258 }
259
260 static SSL *
open_ssl_connection(rfbClient * client,int sockfd,rfbBool anonTLS)261 open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS)
262 {
263 SSL_CTX *ssl_ctx = NULL;
264 SSL *ssl = NULL;
265 int n, finished = 0;
266
267 ssl_ctx = SSL_CTX_new (SSLv23_client_method ());
268 SSL_CTX_set_default_verify_paths (ssl_ctx);
269 SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, &ssl_verify);
270 ssl = SSL_new (ssl_ctx);
271
272 /* TODO: finetune this list, take into account anonTLS bool */
273 SSL_set_cipher_list(ssl, "ALL");
274
275 SSL_set_fd (ssl, sockfd);
276 SSL_CTX_set_app_data (ssl_ctx, client);
277
278 do
279 {
280 n = SSL_connect(ssl);
281
282 if (n != 1)
283 {
284 if (wait_for_data(ssl, n, 1) != 1)
285 {
286 finished = 1;
287 if (ssl->ctx)
288 SSL_CTX_free (ssl->ctx);
289 SSL_free(ssl);
290 SSL_shutdown (ssl);
291
292 return NULL;
293 }
294 }
295 } while( n != 1 && finished != 1 );
296
297 return ssl;
298 }
299
300
301 static rfbBool
InitializeTLSSession(rfbClient * client,rfbBool anonTLS)302 InitializeTLSSession(rfbClient* client, rfbBool anonTLS)
303 {
304 if (client->tlsSession) return TRUE;
305
306 client->tlsSession = open_ssl_connection (client, client->sock, anonTLS);
307
308 if (!client->tlsSession)
309 return FALSE;
310
311 rfbClientLog("TLS session initialized.\n");
312
313 return TRUE;
314 }
315
316 static rfbBool
SetTLSAnonCredential(rfbClient * client)317 SetTLSAnonCredential(rfbClient* client)
318 {
319 rfbClientLog("TLS anonymous credential created.\n");
320 return TRUE;
321 }
322
323 static rfbBool
HandshakeTLS(rfbClient * client)324 HandshakeTLS(rfbClient* client)
325 {
326 int timeout = 15;
327 int ret;
328
329 return TRUE;
330
331 while (timeout > 0 && (ret = SSL_do_handshake(client->tlsSession)) < 0)
332 {
333 if (ret != -1)
334 {
335 rfbClientLog("TLS handshake blocking.\n");
336 #ifdef WIN32
337 Sleep(1000);
338 #else
339 sleep(1);
340 #endif
341 timeout--;
342 continue;
343 }
344 rfbClientLog("TLS handshake failed: -.\n");
345 FreeTLS(client);
346 return FALSE;
347 }
348
349 if (timeout <= 0)
350 {
351 rfbClientLog("TLS handshake timeout.\n");
352 FreeTLS(client);
353 return FALSE;
354 }
355
356 rfbClientLog("TLS handshake done.\n");
357 return TRUE;
358 }
359
360 /* VeNCrypt sub auth. 1 byte auth count, followed by count * 4 byte integers */
361 static rfbBool
ReadVeNCryptSecurityType(rfbClient * client,uint32_t * result)362 ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result)
363 {
364 uint8_t count=0;
365 uint8_t loop=0;
366 uint8_t flag=0;
367 uint32_t tAuth[256], t;
368 char buf1[500],buf2[10];
369 uint32_t authScheme;
370
371 if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
372
373 if (count==0)
374 {
375 rfbClientLog("List of security types is ZERO. Giving up.\n");
376 return FALSE;
377 }
378
379 if (count>sizeof(tAuth))
380 {
381 rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth));
382 return FALSE;
383 }
384
385 rfbClientLog("We have %d security types to read\n", count);
386 authScheme=0;
387 /* now, we have a list of available security types to read ( uint8_t[] ) */
388 for (loop=0;loop<count;loop++)
389 {
390 if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE;
391 t=rfbClientSwap32IfLE(tAuth[loop]);
392 rfbClientLog("%d) Received security type %d\n", loop, t);
393 if (flag) continue;
394 if (t==rfbVeNCryptTLSNone ||
395 t==rfbVeNCryptTLSVNC ||
396 t==rfbVeNCryptTLSPlain ||
397 t==rfbVeNCryptX509None ||
398 t==rfbVeNCryptX509VNC ||
399 t==rfbVeNCryptX509Plain)
400 {
401 flag++;
402 authScheme=t;
403 rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
404 /* send back 4 bytes (in original byte order!) indicating which security type to use */
405 if (!WriteToRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE;
406 }
407 tAuth[loop]=t;
408 }
409 if (authScheme==0)
410 {
411 memset(buf1, 0, sizeof(buf1));
412 for (loop=0;loop<count;loop++)
413 {
414 if (strlen(buf1)>=sizeof(buf1)-1) break;
415 snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
416 strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
417 }
418 rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n",
419 buf1);
420 return FALSE;
421 }
422 *result = authScheme;
423 return TRUE;
424 }
425
426 rfbBool
HandleAnonTLSAuth(rfbClient * client)427 HandleAnonTLSAuth(rfbClient* client)
428 {
429 if (!InitializeTLS() || !InitializeTLSSession(client, TRUE)) return FALSE;
430
431 if (!SetTLSAnonCredential(client)) return FALSE;
432
433 if (!HandshakeTLS(client)) return FALSE;
434
435 return TRUE;
436 }
437
438 rfbBool
HandleVeNCryptAuth(rfbClient * client)439 HandleVeNCryptAuth(rfbClient* client)
440 {
441 uint8_t major, minor, status;
442 uint32_t authScheme;
443 rfbBool anonTLS;
444 // gnutls_certificate_credentials_t x509_cred = NULL;
445
446 if (!InitializeTLS()) return FALSE;
447
448 /* Read VeNCrypt version */
449 if (!ReadFromRFBServer(client, (char *)&major, 1) ||
450 !ReadFromRFBServer(client, (char *)&minor, 1))
451 {
452 return FALSE;
453 }
454 rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor);
455
456 if (major != 0 && minor != 2)
457 {
458 rfbClientLog("Unsupported VeNCrypt version.\n");
459 return FALSE;
460 }
461
462 if (!WriteToRFBServer(client, (char *)&major, 1) ||
463 !WriteToRFBServer(client, (char *)&minor, 1) ||
464 !ReadFromRFBServer(client, (char *)&status, 1))
465 {
466 return FALSE;
467 }
468
469 if (status != 0)
470 {
471 rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor);
472 return FALSE;
473 }
474
475 if (!ReadVeNCryptSecurityType(client, &authScheme)) return FALSE;
476 if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1)
477 {
478 rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status);
479 return FALSE;
480 }
481 client->subAuthScheme = authScheme;
482
483 /* Some VeNCrypt security types are anonymous TLS, others are X509 */
484 switch (authScheme)
485 {
486 case rfbVeNCryptTLSNone:
487 case rfbVeNCryptTLSVNC:
488 case rfbVeNCryptTLSPlain:
489 anonTLS = TRUE;
490 break;
491 default:
492 anonTLS = FALSE;
493 break;
494 }
495
496 /* Get X509 Credentials if it's not anonymous */
497 if (!anonTLS)
498 {
499 rfbCredential *cred;
500
501 if (!client->GetCredential)
502 {
503 rfbClientLog("GetCredential callback is not set.\n");
504 return FALSE;
505 }
506 cred = client->GetCredential(client, rfbCredentialTypeX509);
507 if (!cred)
508 {
509 rfbClientLog("Reading credential failed\n");
510 return FALSE;
511 }
512
513 /* TODO: don't just ignore this
514 x509_cred = CreateX509CertCredential(cred);
515 FreeX509Credential(cred);
516 if (!x509_cred) return FALSE; */
517 }
518
519 /* Start up the TLS session */
520 if (!InitializeTLSSession(client, anonTLS)) return FALSE;
521
522 if (anonTLS)
523 {
524 if (!SetTLSAnonCredential(client)) return FALSE;
525 }
526 else
527 {
528 /* TODO: don't just ignore this
529 if ((ret = gnutls_credentials_set(client->tlsSession, GNUTLS_CRD_CERTIFICATE, x509_cred)) < 0)
530 {
531 rfbClientLog("Cannot set x509 credential: %s.\n", gnutls_strerror(ret));
532 FreeTLS(client); */
533 return FALSE;
534 // }
535 }
536
537 if (!HandshakeTLS(client)) return FALSE;
538
539 /* TODO: validate certificate */
540
541 /* We are done here. The caller should continue with client->subAuthScheme
542 * to do actual sub authentication.
543 */
544 return TRUE;
545 }
546
547 int
ReadFromTLS(rfbClient * client,char * out,unsigned int n)548 ReadFromTLS(rfbClient* client, char *out, unsigned int n)
549 {
550 ssize_t ret;
551
552 ret = SSL_read (client->tlsSession, out, n);
553
554 if (ret >= 0)
555 return ret;
556 else {
557 errno = ssl_errno (client->tlsSession, ret);
558
559 if (errno != EAGAIN) {
560 rfbClientLog("Error reading from TLS: -.\n");
561 }
562 }
563
564 return -1;
565 }
566
567 int
WriteToTLS(rfbClient * client,char * buf,unsigned int n)568 WriteToTLS(rfbClient* client, char *buf, unsigned int n)
569 {
570 unsigned int offset = 0;
571 ssize_t ret;
572
573 while (offset < n)
574 {
575
576 ret = SSL_write (client->tlsSession, buf + offset, (size_t)(n-offset));
577
578 if (ret < 0)
579 errno = ssl_errno (client->tlsSession, ret);
580
581 if (ret == 0) continue;
582 if (ret < 0)
583 {
584 if (errno == EAGAIN || errno == EWOULDBLOCK) continue;
585 rfbClientLog("Error writing to TLS: -\n");
586 return -1;
587 }
588 offset += (unsigned int)ret;
589 }
590 return offset;
591 }
592
FreeTLS(rfbClient * client)593 void FreeTLS(rfbClient* client)
594 {
595 int i;
596
597 if (mutex_buf != NULL) {
598 CRYPTO_set_dynlock_create_callback(NULL);
599 CRYPTO_set_dynlock_lock_callback(NULL);
600 CRYPTO_set_dynlock_destroy_callback(NULL);
601
602 CRYPTO_set_locking_callback(NULL);
603 CRYPTO_set_id_callback(NULL);
604
605 for (i = 0; i < CRYPTO_num_locks(); i++)
606 MUTEX_FREE(mutex_buf[i]);
607 free(mutex_buf);
608 mutex_buf = NULL;
609 }
610
611 SSL_free(client->tlsSession);
612 }
613
614