00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <rfb/rfbclient.h>
00022 #include <errno.h>
00023
00024 #include <openssl/err.h>
00025 #include <openssl/ssl.h>
00026 #include <openssl/x509.h>
00027 #include <openssl/rand.h>
00028 #include <openssl/x509.h>
00029
00030 #include <pthread.h>
00031
00032 #include "tls.h"
00033
00034 static rfbBool rfbTLSInitialized = FALSE;
00035 static pthread_mutex_t *mutex_buf = NULL;
00036
00037 struct CRYPTO_dynlock_value {
00038 pthread_mutex_t mutex;
00039 };
00040
00041 static void locking_function(int mode, int n, const char *file, int line)
00042 {
00043 if (mode & CRYPTO_LOCK)
00044 pthread_mutex_lock(&mutex_buf[n]);
00045 else
00046 pthread_mutex_unlock(&mutex_buf[n]);
00047 }
00048
00049 static unsigned long id_function(void)
00050 {
00051 return ((unsigned long) pthread_self());
00052 }
00053
00054 static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
00055 {
00056 struct CRYPTO_dynlock_value *value;
00057
00058 value = (struct CRYPTO_dynlock_value *)
00059 malloc(sizeof(struct CRYPTO_dynlock_value));
00060 if (!value)
00061 goto err;
00062 pthread_mutex_init(&value->mutex, NULL);
00063
00064 return value;
00065
00066 err:
00067 return (NULL);
00068 }
00069
00070 static void dyn_lock_function (int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
00071 {
00072 if (mode & CRYPTO_LOCK)
00073 pthread_mutex_lock(&l->mutex);
00074 else
00075 pthread_mutex_unlock(&l->mutex);
00076 }
00077
00078
00079 static void
00080 dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
00081 {
00082 pthread_mutex_destroy(&l->mutex);
00083 free(l);
00084 }
00085
00086
00087 static int
00088 ssl_errno (SSL *ssl, int ret)
00089 {
00090 switch (SSL_get_error (ssl, ret)) {
00091 case SSL_ERROR_NONE:
00092 return 0;
00093 case SSL_ERROR_ZERO_RETURN:
00094
00095
00096 return EINVAL;
00097 case SSL_ERROR_WANT_READ:
00098 case SSL_ERROR_WANT_WRITE:
00099
00100 return EAGAIN;
00101 case SSL_ERROR_SYSCALL:
00102
00103 return EINTR;
00104 case SSL_ERROR_SSL:
00105
00106 return EINTR;
00107 default:
00108
00109 return EINTR;
00110 }
00111 }
00112
00113 static rfbBool
00114 InitializeTLS(void)
00115 {
00116 int i;
00117
00118 if (rfbTLSInitialized) return TRUE;
00119
00120 mutex_buf = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
00121 if (mutex_buf == NULL) {
00122 rfbClientLog("Failed to initialized OpenSSL: memory.\n");
00123 return (-1);
00124 }
00125
00126 for (i = 0; i < CRYPTO_num_locks(); i++)
00127 pthread_mutex_init(&mutex_buf[i], NULL);
00128
00129 CRYPTO_set_locking_callback(locking_function);
00130 CRYPTO_set_id_callback(id_function);
00131 CRYPTO_set_dynlock_create_callback(dyn_create_function);
00132 CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
00133 CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
00134 SSL_load_error_strings();
00135 SSLeay_add_ssl_algorithms();
00136 RAND_load_file("/dev/urandom", 1024);
00137
00138 rfbClientLog("OpenSSL initialized.\n");
00139 rfbTLSInitialized = TRUE;
00140 return TRUE;
00141 }
00142
00143 static int
00144 ssl_verify (int ok, X509_STORE_CTX *ctx)
00145 {
00146 unsigned char md5sum[16], fingerprint[40], *f;
00147 rfbClient *client;
00148 char *prompt, *cert_str;
00149 int err, i;
00150 unsigned int md5len;
00151
00152 X509 *cert;
00153 SSL *ssl;
00154
00155 if (ok)
00156 return TRUE;
00157
00158 ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx ());
00159
00160 client = SSL_CTX_get_app_data (ssl->ctx);
00161
00162 cert = X509_STORE_CTX_get_current_cert (ctx);
00163 err = X509_STORE_CTX_get_error (ctx);
00164
00165
00166 md5len = sizeof (md5sum);
00167 X509_digest (cert, EVP_md5 (), md5sum, &md5len);
00168 for (i = 0, f = fingerprint; i < 16; i++, f += 3)
00169 sprintf ((char *) f, "%.2x%c", md5sum[i], i != 15 ? ':' : '\0');
00170
00171 #define GET_STRING(name) X509_NAME_oneline (name, buf, 256)
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 ok = TRUE;
00182
00183 return ok;
00184 }
00185
00186 static int sock_read_ready(SSL *ssl, uint32_t ms)
00187 {
00188 int r = 0;
00189 fd_set fds;
00190 struct timeval tv;
00191
00192 FD_ZERO(&fds);
00193
00194 FD_SET(SSL_get_fd(ssl), &fds);
00195
00196 tv.tv_sec = ms / 1000;
00197 tv.tv_usec = (ms % 1000) * ms;
00198
00199 r = select (SSL_get_fd(ssl) + 1, &fds, NULL, NULL, &tv);
00200
00201 return r;
00202 }
00203
00204 static int wait_for_data(SSL *ssl, int ret, int timeout)
00205 {
00206 struct timeval tv;
00207 fd_set fds;
00208 int err;
00209 int retval = 1;
00210
00211 err = SSL_get_error(ssl, ret);
00212
00213 switch(err)
00214 {
00215 case SSL_ERROR_WANT_READ:
00216 case SSL_ERROR_WANT_WRITE:
00217 ret = sock_read_ready(ssl, timeout*1000);
00218
00219 if (ret == -1) {
00220 retval = 2;
00221 }
00222
00223 break;
00224 default:
00225 retval = 3;
00226 break;
00227 }
00228
00229 ERR_clear_error();
00230
00231 return retval;
00232 }
00233
00234 static SSL *
00235 open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS)
00236 {
00237 SSL_CTX *ssl_ctx = NULL;
00238 SSL *ssl = NULL;
00239 int n, finished = 0;
00240 BIO *sbio;
00241
00242 ssl_ctx = SSL_CTX_new (SSLv23_client_method ());
00243 SSL_CTX_set_default_verify_paths (ssl_ctx);
00244 SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, &ssl_verify);
00245 ssl = SSL_new (ssl_ctx);
00246
00247
00248 SSL_set_cipher_list(ssl, "ALL");
00249
00250 SSL_set_fd (ssl, sockfd);
00251 SSL_CTX_set_app_data (ssl_ctx, client);
00252
00253 do
00254 {
00255 n = SSL_connect(ssl);
00256
00257 if (n != 1)
00258 {
00259 if (wait_for_data(ssl, n, 1) != 1)
00260 {
00261 finished = 1;
00262 if (ssl->ctx)
00263 SSL_CTX_free (ssl->ctx);
00264 SSL_free(ssl);
00265 SSL_shutdown (ssl);
00266
00267 return NULL;
00268 }
00269 }
00270 } while( n != 1 && finished != 1 );
00271
00272 return ssl;
00273 }
00274
00275
00276 static rfbBool
00277 InitializeTLSSession(rfbClient* client, rfbBool anonTLS)
00278 {
00279 int ret;
00280
00281 if (client->tlsSession) return TRUE;
00282
00283 client->tlsSession = open_ssl_connection (client, client->sock, anonTLS);
00284
00285 if (!client->tlsSession)
00286 return FALSE;
00287
00288 rfbClientLog("TLS session initialized.\n");
00289
00290 return TRUE;
00291 }
00292
00293 static rfbBool
00294 SetTLSAnonCredential(rfbClient* client)
00295 {
00296 rfbClientLog("TLS anonymous credential created.\n");
00297 return TRUE;
00298 }
00299
00300 static rfbBool
00301 HandshakeTLS(rfbClient* client)
00302 {
00303 int timeout = 15;
00304 int ret;
00305
00306 return TRUE;
00307
00308 while (timeout > 0 && (ret = SSL_do_handshake(client->tlsSession)) < 0)
00309 {
00310 if (ret != -1)
00311 {
00312 rfbClientLog("TLS handshake blocking.\n");
00313 sleep(1);
00314 timeout--;
00315 continue;
00316 }
00317 rfbClientLog("TLS handshake failed: -.\n");
00318 FreeTLS(client);
00319 return FALSE;
00320 }
00321
00322 if (timeout <= 0)
00323 {
00324 rfbClientLog("TLS handshake timeout.\n");
00325 FreeTLS(client);
00326 return FALSE;
00327 }
00328
00329 rfbClientLog("TLS handshake done.\n");
00330 return TRUE;
00331 }
00332
00333
00334 static rfbBool
00335 ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result)
00336 {
00337 uint8_t count=0;
00338 uint8_t loop=0;
00339 uint8_t flag=0;
00340 uint32_t tAuth[256], t;
00341 char buf1[500],buf2[10];
00342 uint32_t authScheme;
00343
00344 if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE;
00345
00346 if (count==0)
00347 {
00348 rfbClientLog("List of security types is ZERO. Giving up.\n");
00349 return FALSE;
00350 }
00351
00352 if (count>sizeof(tAuth))
00353 {
00354 rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth));
00355 return FALSE;
00356 }
00357
00358 rfbClientLog("We have %d security types to read\n", count);
00359 authScheme=0;
00360
00361 for (loop=0;loop<count;loop++)
00362 {
00363 if (!ReadFromRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE;
00364 t=rfbClientSwap32IfLE(tAuth[loop]);
00365 rfbClientLog("%d) Received security type %d\n", loop, t);
00366 if (flag) continue;
00367 if (t==rfbVeNCryptTLSNone ||
00368 t==rfbVeNCryptTLSVNC ||
00369 t==rfbVeNCryptTLSPlain ||
00370 t==rfbVeNCryptX509None ||
00371 t==rfbVeNCryptX509VNC ||
00372 t==rfbVeNCryptX509Plain)
00373 {
00374 flag++;
00375 authScheme=t;
00376 rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count);
00377
00378 if (!WriteToRFBServer(client, (char *)&tAuth[loop], 4)) return FALSE;
00379 }
00380 tAuth[loop]=t;
00381 }
00382 if (authScheme==0)
00383 {
00384 memset(buf1, 0, sizeof(buf1));
00385 for (loop=0;loop<count;loop++)
00386 {
00387 if (strlen(buf1)>=sizeof(buf1)-1) break;
00388 snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]);
00389 strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1);
00390 }
00391 rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n",
00392 buf1);
00393 return FALSE;
00394 }
00395 *result = authScheme;
00396 return TRUE;
00397 }
00398
00399 rfbBool
00400 HandleAnonTLSAuth(rfbClient* client)
00401 {
00402 if (!InitializeTLS() || !InitializeTLSSession(client, TRUE)) return FALSE;
00403
00404 if (!SetTLSAnonCredential(client)) return FALSE;
00405
00406 if (!HandshakeTLS(client)) return FALSE;
00407
00408 return TRUE;
00409 }
00410
00411 rfbBool
00412 HandleVeNCryptAuth(rfbClient* client)
00413 {
00414 uint8_t major, minor, status;
00415 uint32_t authScheme;
00416 rfbBool anonTLS;
00417
00418 int ret;
00419
00420 if (!InitializeTLS()) return FALSE;
00421
00422
00423 if (!ReadFromRFBServer(client, (char *)&major, 1) ||
00424 !ReadFromRFBServer(client, (char *)&minor, 1))
00425 {
00426 return FALSE;
00427 }
00428 rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor);
00429
00430 if (major != 0 && minor != 2)
00431 {
00432 rfbClientLog("Unsupported VeNCrypt version.\n");
00433 return FALSE;
00434 }
00435
00436 if (!WriteToRFBServer(client, (char *)&major, 1) ||
00437 !WriteToRFBServer(client, (char *)&minor, 1) ||
00438 !ReadFromRFBServer(client, (char *)&status, 1))
00439 {
00440 return FALSE;
00441 }
00442
00443 if (status != 0)
00444 {
00445 rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor);
00446 return FALSE;
00447 }
00448
00449 if (!ReadVeNCryptSecurityType(client, &authScheme)) return FALSE;
00450 if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1)
00451 {
00452 rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status);
00453 return FALSE;
00454 }
00455 client->subAuthScheme = authScheme;
00456
00457
00458 switch (authScheme)
00459 {
00460 case rfbVeNCryptTLSNone:
00461 case rfbVeNCryptTLSVNC:
00462 case rfbVeNCryptTLSPlain:
00463 anonTLS = TRUE;
00464 break;
00465 default:
00466 anonTLS = FALSE;
00467 break;
00468 }
00469
00470
00471 if (!anonTLS)
00472 {
00473 rfbCredential *cred;
00474
00475 if (!client->GetCredential)
00476 {
00477 rfbClientLog("GetCredential callback is not set.\n");
00478 return FALSE;
00479 }
00480 cred = client->GetCredential(client, rfbCredentialTypeX509);
00481 if (!cred)
00482 {
00483 rfbClientLog("Reading credential failed\n");
00484 return FALSE;
00485 }
00486
00487
00488
00489
00490
00491 }
00492
00493
00494 if (!InitializeTLSSession(client, anonTLS)) return FALSE;
00495
00496 if (anonTLS)
00497 {
00498 if (!SetTLSAnonCredential(client)) return FALSE;
00499 }
00500 else
00501 {
00502
00503
00504
00505
00506
00507 return FALSE;
00508
00509 }
00510
00511 if (!HandshakeTLS(client)) return FALSE;
00512
00513
00514
00515
00516
00517
00518 return TRUE;
00519 }
00520
00521 int
00522 ReadFromTLS(rfbClient* client, char *out, unsigned int n)
00523 {
00524 ssize_t ret;
00525
00526 ret = SSL_read (client->tlsSession, out, n);
00527
00528 if (ret >= 0)
00529 return ret;
00530 else {
00531 errno = ssl_errno (client->tlsSession, ret);
00532
00533 if (errno != EAGAIN) {
00534 rfbClientLog("Error reading from TLS: -.\n");
00535 }
00536 }
00537
00538 return -1;
00539 }
00540
00541 int
00542 WriteToTLS(rfbClient* client, char *buf, unsigned int n)
00543 {
00544 unsigned int offset = 0;
00545 ssize_t ret;
00546
00547 while (offset < n)
00548 {
00549
00550 ret = SSL_write (client->tlsSession, buf + offset, (size_t)(n-offset));
00551
00552 if (ret < 0)
00553 errno = ssl_errno (client->tlsSession, ret);
00554
00555 if (ret == 0) continue;
00556 if (ret < 0)
00557 {
00558 if (errno == EAGAIN || errno == EWOULDBLOCK) continue;
00559 rfbClientLog("Error writing to TLS: -\n");
00560 return -1;
00561 }
00562 offset += (unsigned int)ret;
00563 }
00564 return offset;
00565 }
00566
00567 void FreeTLS(rfbClient* client)
00568 {
00569 int i;
00570
00571 if (mutex_buf != NULL) {
00572 CRYPTO_set_dynlock_create_callback(NULL);
00573 CRYPTO_set_dynlock_lock_callback(NULL);
00574 CRYPTO_set_dynlock_destroy_callback(NULL);
00575
00576 CRYPTO_set_locking_callback(NULL);
00577 CRYPTO_set_id_callback(NULL);
00578
00579 for (i = 0; i < CRYPTO_num_locks(); i++)
00580 pthread_mutex_destroy(&mutex_buf[i]);
00581 free(mutex_buf);
00582 mutex_buf = NULL;
00583 }
00584
00585 SSL_free(client->tlsSession);
00586 }
00587