1 /* 2 * Copyright (C) 2012 Philip Van Hoof <philip (at) 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 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 78 static unsigned long id_function(void) 79 { 80 return ((unsigned long) CURRENT_THREAD_ID); 81 } 82 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 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 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 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 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 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 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 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 * 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 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 317 SetTLSAnonCredential(rfbClient* client) 318 { 319 rfbClientLog("TLS anonymous credential created.\n"); 320 return TRUE; 321 } 322 323 static rfbBool 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 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 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 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 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 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 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