mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-01-03 14:56:34 -05:00
Update: Abstracted the TLS context code into tls.c
This commit is contained in:
parent
b7087c38e0
commit
64b16f8296
@ -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();
|
||||
|
138
src/tls.c
Normal file
138
src/tls.c
Normal file
@ -0,0 +1,138 @@
|
||||
/* 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
|
30
src/tls.h
Normal file
30
src/tls.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* 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
|
Loading…
Reference in New Issue
Block a user