/*
 * rfbssl_openssl.c - Secure socket funtions (openssl version)
 */

/*
 *  Copyright (C) 2011 Gernot Tenchio
 *
 *  This is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This software is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this software; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 *  USA.
 */

#include "rfbssl.h"
#include <openssl/ssl.h>
#include <openssl/err.h>

struct rfbssl_ctx {
    SSL_CTX *ssl_ctx;
    SSL     *ssl;
};

static void rfbssl_error(void)
{
    char buf[1024];
    unsigned long e = ERR_get_error();
    rfbErr("%s (%ld)\n", ERR_error_string(e, buf), e);
}

int rfbssl_init(rfbClientPtr cl)
{
    char *keyfile;
    int r, ret = -1;
    struct rfbssl_ctx *ctx;

    SSL_library_init();
    SSL_load_error_strings();

    if (cl->screen->sslkeyfile && *cl->screen->sslkeyfile) {
      keyfile = cl->screen->sslkeyfile;
    } else {
      keyfile = cl->screen->sslcertfile;
    }

    if (NULL == (ctx = malloc(sizeof(struct rfbssl_ctx)))) {
	rfbErr("OOM\n");
    } else if (!cl->screen->sslcertfile || !cl->screen->sslcertfile[0]) {
	rfbErr("SSL connection but no cert specified\n");
    } else if (NULL == (ctx->ssl_ctx = SSL_CTX_new(TLSv1_server_method()))) {
	rfbssl_error();
    } else if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, keyfile, SSL_FILETYPE_PEM) <= 0) {
	rfbErr("Unable to load private key file %s\n", keyfile);
    } else if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, cl->screen->sslcertfile, SSL_FILETYPE_PEM) <= 0) {
	rfbErr("Unable to load certificate file %s\n", cl->screen->sslcertfile);
    } else if (NULL == (ctx->ssl = SSL_new(ctx->ssl_ctx))) {
	rfbErr("SSL_new failed\n");
	rfbssl_error();
    } else if (!(SSL_set_fd(ctx->ssl, cl->sock))) {
	rfbErr("SSL_set_fd failed\n");
	rfbssl_error();
    } else {
	while ((r = SSL_accept(ctx->ssl)) < 0) {
	    if (SSL_get_error(ctx->ssl, r) != SSL_ERROR_WANT_READ)
		break;
	}
	if (r < 0) {
	    rfbErr("SSL_accept failed %d\n", SSL_get_error(ctx->ssl, r));
	} else {
	    cl->sslctx = (rfbSslCtx *)ctx;
	    ret = 0;
	}
    }
    return ret;
}

int rfbssl_write(rfbClientPtr cl, const char *buf, int bufsize)
{
    int ret;
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;

    while ((ret = SSL_write(ctx->ssl, buf, bufsize)) <= 0) {
	if (SSL_get_error(ctx->ssl, ret) != SSL_ERROR_WANT_WRITE)
	    break;
    }
    return ret;
}

int rfbssl_peek(rfbClientPtr cl, char *buf, int bufsize)
{
    int ret;
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;

    while ((ret = SSL_peek(ctx->ssl, buf, bufsize)) <= 0) {
	if (SSL_get_error(ctx->ssl, ret) != SSL_ERROR_WANT_READ)
	    break;
    }
    return ret;
}

int rfbssl_read(rfbClientPtr cl, char *buf, int bufsize)
{
    int ret;
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;

    while ((ret = SSL_read(ctx->ssl, buf, bufsize)) <= 0) {
	if (SSL_get_error(ctx->ssl, ret) != SSL_ERROR_WANT_READ)
	    break;
    }
    return ret;
}

int rfbssl_pending(rfbClientPtr cl)
{
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
    return SSL_pending(ctx->ssl);
}

void rfbssl_destroy(rfbClientPtr cl)
{
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
    if (ctx->ssl)
	SSL_free(ctx->ssl);
    if (ctx->ssl_ctx)
	SSL_CTX_free(ctx->ssl_ctx);
}
