Commit 64b16f82 authored by Philipp Schafft's avatar Philipp Schafft 🦁

Update: Abstracted the TLS context code into tls.c

parent b7087c38
......@@ -16,7 +16,7 @@ noinst_HEADERS = admin.h cfgfile.h logging.h sighandler.h connection.h \
format_kate.h format_skeleton.h format_opus.h
icecast_SOURCES = cfgfile.c main.c logging.c sighandler.c connection.c global.c \
util.c slave.c source.c stats.c refbuf.c client.c playlist.c \
xslt.c fserve.c admin.c md5.c matchfile.c \
xslt.c fserve.c admin.c md5.c matchfile.c tls.c \
format.c format_ogg.c format_mp3.c format_midi.c format_flac.c format_ebml.c \
format_kate.c format_skeleton.c format_opus.c \
event.c event_log.c event_exec.c \
......
......@@ -59,6 +59,7 @@
#include "admin.h"
#include "auth.h"
#include "matchfile.h"
#include "tls.h"
#define CATMODULE "connection"
......@@ -98,9 +99,7 @@ static int _initialized = 0;
static volatile client_queue_t *_req_queue = NULL, **_req_queue_tail = &_req_queue;
static volatile client_queue_t *_con_queue = NULL, **_con_queue_tail = &_con_queue;
static int ssl_ok;
#ifdef HAVE_OPENSSL
static SSL_CTX *ssl_ctx;
#endif
static tls_ctx_t *tls_ctx;
/* filtering client connection based on IP */
static matchfile_t *banned_ip, *allowed_ip;
......@@ -131,9 +130,7 @@ void connection_shutdown(void)
if (!_initialized)
return;
#ifdef HAVE_OPENSSL
SSL_CTX_free (ssl_ctx);
#endif
tls_ctx_unref(tls_ctx);
matchfile_release(banned_ip);
matchfile_release(allowed_ip);
......@@ -160,46 +157,16 @@ static unsigned long _next_connection_id(void)
#ifdef HAVE_OPENSSL
static void get_ssl_certificate(ice_config_t *config)
{
SSL_METHOD *method;
long ssl_opts;
config->tls_ok = ssl_ok = 0;
SSL_load_error_strings(); /* readable error messages */
SSL_library_init(); /* initialize library */
method = SSLv23_server_method();
ssl_ctx = SSL_CTX_new(method);
ssl_opts = SSL_CTX_get_options(ssl_ctx);
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(ssl_ctx, ssl_opts|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION);
#else
SSL_CTX_set_options(ssl_ctx, ssl_opts|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
#endif
do {
if (config->cert_file == NULL)
break;
if (SSL_CTX_use_certificate_chain_file (ssl_ctx, config->cert_file) <= 0) {
ICECAST_LOG_WARN("Invalid cert file %s", config->cert_file);
break;
}
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, config->cert_file, SSL_FILETYPE_PEM) <= 0) {
ICECAST_LOG_WARN("Invalid private key file %s", config->cert_file);
break;
}
if (!SSL_CTX_check_private_key (ssl_ctx)) {
ICECAST_LOG_ERROR("Invalid %s - Private key does not match cert public key", config->cert_file);
break;
}
if (SSL_CTX_set_cipher_list(ssl_ctx, config->cipher_list) <= 0) {
ICECAST_LOG_WARN("Invalid cipher list: %s", config->cipher_list);
}
config->tls_ok = ssl_ok = 1;
ICECAST_LOG_INFO("Certificate found at %s", config->cert_file);
ICECAST_LOG_INFO("Using ciphers %s", config->cipher_list);
tls_ctx_unref(tls_ctx);
tls_ctx = tls_ctx_new(config->cert_file, config->cert_file, config->cipher_list);
if (!tls_ctx) {
ICECAST_LOG_INFO("No TLS capability on any configured ports");
return;
} while (0);
ICECAST_LOG_INFO("No TLS capability on any configured ports");
}
config->tls_ok = ssl_ok = 1;
}
......@@ -301,7 +268,7 @@ void connection_uses_ssl(connection_t *con)
con->read = connection_read_ssl;
con->send = connection_send_ssl;
con->ssl = SSL_new(ssl_ctx);
con->ssl = tls_ctx_SSL_new(tls_ctx);
SSL_set_accept_state(con->ssl);
SSL_set_fd(con->ssl, con->sock);
#endif
......
......@@ -123,6 +123,7 @@ void initialize_subsystems(void)
sock_initialize();
resolver_initialize();
config_initialize();
tls_initialize();
connection_initialize();
global_initialize();
refbuf_initialize();
......@@ -145,6 +146,7 @@ void shutdown_subsystems(void)
global_shutdown();
connection_shutdown();
tls_shutdown();
config_shutdown();
resolver_shutdown();
sock_shutdown();
......
/* Icecast
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2016, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
*/
/**
* TLS support functions
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include "tls.h"
#include "logging.h"
#define CATMODULE "tls"
#ifdef HAVE_OPENSSL
struct tls_ctx_tag {
size_t refc;
SSL_CTX *ctx;
};
void tls_initialize(void)
{
SSL_load_error_strings(); /* readable error messages */
SSL_library_init(); /* initialize library */
}
void tls_shutdown(void)
{
}
tls_ctx_t *tls_ctx_new(const char *cert_file, const char *key_file, const char *cipher_list)
{
tls_ctx_t *ctx;
SSL_METHOD *method;
long ssl_opts;
if (!cert_file || !key_file || !cipher_list)
return NULL;
ctx = calloc(1, sizeof(*ctx));
if (!ctx)
return NULL;
method = SSLv23_server_method();
ctx->refc = 1;
ctx->ctx = SSL_CTX_new(method);
ssl_opts = SSL_CTX_get_options(ctx->ctx);
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(ctx->ctx, ssl_opts|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_COMPRESSION);
#else
SSL_CTX_set_options(ctx->ctx, ssl_opts|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
#endif
do {
if (SSL_CTX_use_certificate_chain_file(ctx->ctx, cert_file) <= 0) {
ICECAST_LOG_WARN("Invalid cert file %s", cert_file);
break;
}
if (SSL_CTX_use_PrivateKey_file(ctx->ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
ICECAST_LOG_WARN("Invalid private key file %s", key_file);
break;
}
if (!SSL_CTX_check_private_key(ctx->ctx)) {
ICECAST_LOG_ERROR("Invalid %s - Private key does not match cert public key", key_file);
break;
}
if (SSL_CTX_set_cipher_list(ctx->ctx, cipher_list) <= 0) {
ICECAST_LOG_WARN("Invalid cipher list: %s", cipher_list);
}
ICECAST_LOG_INFO("Certificate found at %s", cert_file);
ICECAST_LOG_INFO("Using ciphers %s", cipher_list);
return ctx;
} while (0);
ICECAST_LOG_INFO("Can not setup TLS.");
tls_ctx_unref(ctx);
return NULL;
}
void tls_ctx_ref(tls_ctx_t *ctx)
{
if (!ctx)
return;
ctx->refc++;
}
void tls_ctx_unref(tls_ctx_t *ctx)
{
if (!ctx)
return;
ctx->refc--;
if (ctx->refc)
return;
if (ctx->ctx)
SSL_CTX_free(ctx->ctx);
free(ctx);
}
SSL *tls_ctx_SSL_new(tls_ctx_t *ctx)
{
if (!ctx)
return NULL;
return SSL_new(ctx->ctx);
}
#else
void tls_initialize(void)
{
}
void tls_shutdown(void)
{
}
tls_ctx_t *tls_ctx_new(const char *cert_file, const char *key_file, const char *cipher_list)
{
return NULL;
}
void tls_ctx_ref(tls_ctx_t *ctx)
{
}
void tls_ctx_unref(tls_ctx_t *ctx)
{
}
#endif
/* Icecast
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2016, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
*/
#ifndef __TLS_H__
#define __TLS_H__
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
typedef struct tls_ctx_tag tls_ctx_t;
void tls_initialize(void);
void tls_shutdown(void);
tls_ctx_t *tls_ctx_new(const char *cert_file, const char *key_file, const char *cipher_list);
void tls_ctx_ref(tls_ctx_t *ctx);
void tls_ctx_unref(tls_ctx_t *ctx);
#ifdef HAVE_OPENSSL
SSL *tls_ctx_SSL_new(tls_ctx_t *ctx);
#endif
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment