1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-30 06:35:23 +00:00

initial ssl port handling work

svn path=/icecast/branches/kh/icecast/; revision=9656
This commit is contained in:
Karl Heyes 2005-07-30 17:16:21 +00:00
parent 29f3d6639b
commit eadfcbe19f
8 changed files with 158 additions and 12 deletions

View File

@ -53,6 +53,7 @@
<!--
<listen-socket>
<port>8001</port>
<ssl>1</ssl>
</listen-socket>
-->
@ -158,6 +159,7 @@
<webroot>@pkgdatadir@/web</webroot>
<adminroot>@pkgdatadir@/admin</adminroot>
<!-- <pidfile>@pkgdatadir@/icecast.pid</pidfile> -->
<!-- <ssl_certificate>@pkgdatadir@/icecast.pem</ssl_certificate> -->
<!-- Aliases: treat requests for 'source' path as being for 'dest' path
May be made specific to a port or bound address using the "port"

View File

@ -130,6 +130,14 @@ then
else
AC_MSG_NOTICE([YP support disabled])
fi
XIPH_PATH_OPENSSL([
XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$OPENSSL_CFLAGS])
XIPH_VAR_APPEND([XIPH_LDFLAGS],[$OPENSSL_LDFLAGS])
XIPH_VAR_PREPEND([XIPH_LIBS],[$OPENSSL_LIBS])
],
[ AC_MSG_NOTICE([SSL disabled!])
])
# don't log ip's in the access log
AC_ARG_ENABLE([log-ip],
AC_HELP_STRING([--disable-log-ip],[disable logging of IP's in access log]),

View File

@ -354,6 +354,9 @@ void add_client (const char *mount, client_t *client)
mount_proxy *mountinfo;
ice_config_t *config = config_get_config();
/* we don't need any more data from the listener, just setup for writing */
client->refbuf->len = PER_CLIENT_REFBUF_SIZE;
mountinfo = config_find_mount (config, mount);
if (mountinfo && mountinfo->auth)
{

View File

@ -794,6 +794,11 @@ static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
listener->shoutcast_compat = atoi(tmp);
if(tmp) xmlFree(tmp);
}
else if (strcmp(node->name, "ssl") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
listener->ssl = atoi(tmp);
if(tmp) xmlFree(tmp);
}
else if (strcmp(node->name, "bind-address") == 0) {
listener->bind_address = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
@ -900,6 +905,9 @@ static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
} else if (strcmp(node->name, "pidfile") == 0) {
if (configuration->pidfile) xmlFree(configuration->pidfile);
configuration->pidfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "ssl_certificate") == 0) {
if (configuration->cert_file) xmlFree(configuration->cert_file);
configuration->cert_file = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (strcmp(node->name, "webroot") == 0) {
if (configuration->webroot_dir && configuration->webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(configuration->webroot_dir);
configuration->webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);

View File

@ -97,6 +97,7 @@ typedef struct {
int port;
char *bind_address;
int shoutcast_compat;
int ssl;
} listener_t;
typedef struct ice_config_tag
@ -147,6 +148,7 @@ typedef struct ice_config_tag
char *base_dir;
char *log_dir;
char *pidfile;
char *cert_file;
char *webroot_dir;
char *adminroot_dir;
aliases *aliases;

View File

@ -148,15 +148,34 @@ int client_read_bytes (client_t *client, void *buf, unsigned len)
client->refbuf->len -= len;
return len;
}
bytes = sock_read_bytes (client->con->sock, buf, len);
#ifdef HAVE_OPENSSL
if (client->con->ssl)
bytes = SSL_read (client->con->ssl, buf, len);
else
#endif
bytes = sock_read_bytes (client->con->sock, buf, len);
if (bytes > 0)
return bytes;
if (bytes < 0)
{
if (sock_recoverable (sock_error()))
return -1;
WARN0 ("source connection has died");
#ifdef HAVE_OPENSSL
if (client->con->ssl)
{
switch (SSL_get_error (client->con->ssl, bytes))
{
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
return -1;
}
bytes = -1;
}
else
#endif
if (sock_recoverable (sock_error()))
return -1;
WARN0 ("reading from connection has failed");
}
client->con->error = 1;
return bytes;
@ -241,16 +260,36 @@ int client_send_bytes (client_t *client, const void *buf, unsigned len)
return -1;
ret = aio_return (aiocbp);
if (ret < 0)
sock_set_error (err); /* make sure errno gets set */
sock_set_error (err); /* make sure errno gets set */
client->pending_io = 0;
#else
int ret = sock_write_bytes (client->con->sock, buf, len);
int ret;
#ifdef HAVE_OPENSSL
if (client->con->ssl)
ret = SSL_write (client->con->ssl, buf, len);
else
#endif
ret = sock_write_bytes (client->con->sock, buf, len);
#endif
if (ret < 0 && !sock_recoverable (sock_error()))
if (ret < 0)
{
#ifdef HAVE_OPENSSL
if (client->con->ssl)
{
switch (SSL_get_error (client->con->ssl, ret))
{
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
return -1;
}
ret = -1;
}
else
#endif
if (sock_recoverable (sock_error()))
return -1;
DEBUG0 ("Client connection died");
client->con->error = 1;
}

View File

@ -33,6 +33,9 @@
#define strcasecmp stricmp
#define strncasecmp strnicmp
#endif
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#endif
#include "os.h"
@ -102,6 +105,10 @@ static volatile client_queue_t *_req_queue = NULL, **_req_queue_tail = &_req_que
static volatile client_queue_t *_con_queue = NULL, **_con_queue_tail = &_con_queue;
static mutex_t _con_queue_mutex;
static mutex_t _req_queue_mutex;
#ifdef HAVE_OPENSSL
static SSL_CTX *ssl_ctx;
static int ssl_ok;
#endif
rwlock_t _source_shutdown_rwlock;
@ -121,10 +128,58 @@ void connection_initialize(void)
_initialized = 1;
}
static void get_ssl_certificate ()
{
#ifdef HAVE_OPENSSL
SSL_METHOD *method;
ice_config_t *config;
SSL_load_error_strings(); /* readable error messages */
SSL_library_init(); /* initialize library */
method = SSLv23_server_method();
ssl_ctx = SSL_CTX_new (method);
ssl_ok = 0;
config = config_get_config ();
do
{
if (config->cert_file == NULL)
break;
if (SSL_CTX_use_certificate_file (ssl_ctx, config->cert_file, SSL_FILETYPE_PEM) <= 0)
{
WARN1 ("Invalid cert file %s", config->cert_file);
break;
}
if (SSL_CTX_use_PrivateKey_file (ssl_ctx, config->cert_file, SSL_FILETYPE_PEM) <= 0)
{
WARN1 ("Invalid private key file %s", config->cert_file);
break;
}
if (!SSL_CTX_check_private_key (ssl_ctx))
{
ERROR0 ("Invalid icecast.pem - Private key doesn't"
" match cert public key");
break;
}
ssl_ok = 1;
} while (0);
config_release_config ();
if (ssl_ok == 0)
#endif
INFO0 ("No SSL capability on the configured ports");
}
void connection_shutdown(void)
{
if (!_initialized) return;
#ifdef HAVE_OPENSSL
SSL_CTX_free (ssl_ctx);
#endif
thread_cond_destroy(&global.shutdown_cond);
thread_rwlock_destroy(&_source_shutdown_rwlock);
thread_mutex_destroy(&_con_queue_mutex);
@ -324,7 +379,7 @@ static void process_request_queue ()
{
client_queue_t *node = *node_ref;
client_t *client = node->client;
int len = client->refbuf->len - node->offset;
int len = PER_CLIENT_REFBUF_SIZE - node->offset;
char *buf = client->refbuf->data + node->offset;
if (len > 0)
@ -332,7 +387,7 @@ static void process_request_queue ()
if (client->con->con_time + timeout <= global.time)
len = 0;
else
len = sock_read_bytes (client->con->sock, buf, len);
len = client_read_bytes (client, buf, len);
}
if (len > 0)
@ -380,7 +435,7 @@ static void process_request_queue ()
}
else
{
if (len == 0 || !sock_recoverable (sock_error()))
if (len == 0 || client->con->error)
{
if ((client_queue_t **)_req_queue_tail == &node->next)
_req_queue_tail = (volatile client_queue_t **)node_ref;
@ -411,6 +466,7 @@ void connection_accept_loop(void)
{
connection_t *con;
get_ssl_certificate ();
tid = thread_create ("connection thread", _handle_connection, NULL, THREAD_ATTACHED);
while (global.running == ICE_RUNNING)
@ -436,7 +492,7 @@ void connection_accept_loop(void)
/* setup client for reading incoming http */
client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';
client->refbuf->len--; /* make sure we are nul terminated */
client->refbuf->len = 0; /* force reader code to ignore buffer */
node = calloc (1, sizeof (client_queue_t));
if (node == NULL)
@ -451,11 +507,29 @@ void connection_accept_loop(void)
for (i = 0; i < global.server_sockets; i++)
{
if (global.serversock[i] == con->serversock)
{
if (config->listeners[i].shoutcast_compat)
node->shoutcast = 1;
#ifdef HAVE_OPENSSL
if (config->listeners[i].ssl && ssl_ok)
{
client->con->ssl = SSL_new (ssl_ctx);
SSL_set_accept_state (client->con->ssl);
SSL_set_fd (client->con->ssl, client->con->sock);
}
#endif
}
}
config_release_config();
#ifdef HAVE_OPENSSL
if (node->shoutcast && client->con->ssl)
{
client_destroy (client);
free (node);
continue;
}
#endif
sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
sock_set_nodelay (client->con->sock);
@ -1045,5 +1119,8 @@ void connection_close(connection_t *con)
sock_close(con->sock);
if (con->ip) free(con->ip);
if (con->host) free(con->host);
#ifdef HAVE_OPENSSL
if (con->ssl) { SSL_shutdown (con->ssl); SSL_free (con->ssl); }
#endif
free(con);
}

View File

@ -15,6 +15,9 @@
#include <sys/types.h>
#include <time.h>
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#endif
#include "compat.h"
#include "httpp/httpp.h"
#include "thread/thread.h"
@ -35,6 +38,10 @@ typedef struct connection_tag
int serversock;
int error;
#ifdef HAVE_OPENSSL
/* SSL handler */
SSL *ssl;
#endif
char *ip;
char *host;