NetBSD/libexec/httpd/ssl-bozo.c

166 lines
4.2 KiB
C

/* $NetBSD: ssl-bozo.c,v 1.4 2008/05/10 19:25:20 mlelstv Exp $ */
/* $eterna: ssl-bozo.c,v 1.7 2008/03/03 03:36:12 mrg Exp $ */
/*
* Copyright (c) 1997-2008 Matthew R. Green
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer and
* dedication in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/* this code implements SSL for bozohttpd */
#ifndef NO_SSL_SUPPORT
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "bozohttpd.h"
static SSL_CTX *ssl_context;
static const SSL_METHOD *ssl_method;
static SSL *bozossl;
static char *certificate_file;
static char *privatekey_file;
static int ssl_printf(const char *, ...);
static ssize_t ssl_read(int, void *, size_t);
static ssize_t ssl_write(int, const void *, size_t);
static int ssl_flush(FILE *);
void
ssl_init(void)
{
if (!certificate_file)
return;
SSL_library_init();
SSL_load_error_strings();
ssl_method = SSLv23_server_method();
ssl_context = SSL_CTX_new(ssl_method);
/* XXX we need to learn how to check the SSL stack for more info */
if (ssl_context == NULL)
error(1, "SSL context initialization failed.");
SSL_CTX_use_certificate_file(ssl_context, certificate_file,
SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ssl_context, privatekey_file,
SSL_FILETYPE_PEM);
/* check consistency of key vs certificate */
if (!SSL_CTX_check_private_key(ssl_context))
error(1, "check private key failed");
}
void
ssl_accept()
{
if (ssl_context) {
bozossl = SSL_new(ssl_context); /* XXX global sucks */
SSL_set_rfd(bozossl, 0);
SSL_set_wfd(bozossl, 1);
SSL_accept(bozossl);
}
}
void
ssl_destroy()
{
if (bozossl)
SSL_free(bozossl);
}
void
ssl_set_opts(char *cert, char *priv)
{
certificate_file = cert;
privatekey_file = priv;
debug((DEBUG_NORMAL, "using cert/priv files: %s & %s", certificate_file,
privatekey_file));
if (Iflag_set == 0)
Iflag = "https";
bozoprintf = ssl_printf;
bozoread = ssl_read;
bozowrite = ssl_write;
bozoflush = ssl_flush;
}
static int
ssl_printf(const char * fmt, ...)
{
int nbytes;
char *buf;
va_list ap;
/* XXX we need more elegant/proper handling of SSL_write return */
va_start(ap, fmt);
if ((nbytes = vasprintf(&buf, fmt, ap)) != -1)
SSL_write(bozossl, buf, nbytes);
va_end(ap);
return nbytes;
}
static ssize_t
ssl_read(int fd, void *buf, size_t nbytes)
{
ssize_t rbytes;
/* XXX we need elegant/proper handling of SSL_read return */
rbytes = (ssize_t)SSL_read(bozossl, buf, nbytes);
if (1 > rbytes) {
if (SSL_get_error(bozossl, rbytes) == SSL_ERROR_WANT_READ)
warning("SSL_ERROR_WANT_READ");
else
warning("SSL_ERROR OTHER");
}
return rbytes;
}
static ssize_t
ssl_write(int fd, const void *buf, size_t nbytes)
{
ssize_t wbytes;
/* XXX we need elegant/proper handling of SSL_write return */
wbytes = (ssize_t)SSL_write(bozossl, buf, nbytes);
return wbytes;
}
static int
ssl_flush(FILE *fp)
{
/* nothing to see here, move right along */
return 0;
}
#endif /* NO_SSL_SUPPORT */