Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "rfbssl.h"
00025 #include <openssl/ssl.h>
00026 #include <openssl/err.h>
00027
00028 struct rfbssl_ctx {
00029 SSL_CTX *ssl_ctx;
00030 SSL *ssl;
00031 };
00032
00033 static void rfbssl_error(void)
00034 {
00035 char buf[1024];
00036 unsigned long e = ERR_get_error();
00037 rfbErr("%s (%ld)\n", ERR_error_string(e, buf), e);
00038 }
00039
00040 int rfbssl_init(rfbClientPtr cl)
00041 {
00042 char *keyfile;
00043 int r, ret = -1;
00044 struct rfbssl_ctx *ctx;
00045
00046 SSL_library_init();
00047 SSL_load_error_strings();
00048
00049 if (cl->screen->sslkeyfile && *cl->screen->sslkeyfile) {
00050 keyfile = cl->screen->sslkeyfile;
00051 } else {
00052 keyfile = cl->screen->sslcertfile;
00053 }
00054
00055 if (NULL == (ctx = malloc(sizeof(struct rfbssl_ctx)))) {
00056 rfbErr("OOM\n");
00057 } else if (!cl->screen->sslcertfile || !cl->screen->sslcertfile[0]) {
00058 rfbErr("SSL connection but no cert specified\n");
00059 } else if (NULL == (ctx->ssl_ctx = SSL_CTX_new(TLSv1_server_method()))) {
00060 rfbssl_error();
00061 } else if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, keyfile, SSL_FILETYPE_PEM) <= 0) {
00062 rfbErr("Unable to load private key file %s\n", keyfile);
00063 } else if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, cl->screen->sslcertfile, SSL_FILETYPE_PEM) <= 0) {
00064 rfbErr("Unable to load certificate file %s\n", cl->screen->sslcertfile);
00065 } else if (NULL == (ctx->ssl = SSL_new(ctx->ssl_ctx))) {
00066 rfbErr("SSL_new failed\n");
00067 rfbssl_error();
00068 } else if (!(SSL_set_fd(ctx->ssl, cl->sock))) {
00069 rfbErr("SSL_set_fd failed\n");
00070 rfbssl_error();
00071 } else {
00072 while ((r = SSL_accept(ctx->ssl)) < 0) {
00073 if (SSL_get_error(ctx->ssl, r) != SSL_ERROR_WANT_READ)
00074 break;
00075 }
00076 if (r < 0) {
00077 rfbErr("SSL_accept failed %d\n", SSL_get_error(ctx->ssl, r));
00078 } else {
00079 cl->sslctx = (rfbSslCtx *)ctx;
00080 ret = 0;
00081 }
00082 }
00083 return ret;
00084 }
00085
00086 int rfbssl_write(rfbClientPtr cl, const char *buf, int bufsize)
00087 {
00088 int ret;
00089 struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
00090
00091 while ((ret = SSL_write(ctx->ssl, buf, bufsize)) <= 0) {
00092 if (SSL_get_error(ctx->ssl, ret) != SSL_ERROR_WANT_WRITE)
00093 break;
00094 }
00095 return ret;
00096 }
00097
00098 int rfbssl_peek(rfbClientPtr cl, char *buf, int bufsize)
00099 {
00100 int ret;
00101 struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
00102
00103 while ((ret = SSL_peek(ctx->ssl, buf, bufsize)) <= 0) {
00104 if (SSL_get_error(ctx->ssl, ret) != SSL_ERROR_WANT_READ)
00105 break;
00106 }
00107 return ret;
00108 }
00109
00110 int rfbssl_read(rfbClientPtr cl, char *buf, int bufsize)
00111 {
00112 int ret;
00113 struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
00114
00115 while ((ret = SSL_read(ctx->ssl, buf, bufsize)) <= 0) {
00116 if (SSL_get_error(ctx->ssl, ret) != SSL_ERROR_WANT_READ)
00117 break;
00118 }
00119 return ret;
00120 }
00121
00122 int rfbssl_pending(rfbClientPtr cl)
00123 {
00124 struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
00125 return SSL_pending(ctx->ssl);
00126 }
00127
00128 void rfbssl_destroy(rfbClientPtr cl)
00129 {
00130 struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
00131 if (ctx->ssl)
00132 SSL_free(ctx->ssl);
00133 if (ctx->ssl_ctx)
00134 SSL_CTX_free(ctx->ssl_ctx);
00135 }