[xiph-commits] r9656 - in icecast/branches/kh/icecast: . conf src
karl at svn.xiph.org
karl at svn.xiph.org
Sat Jul 30 10:16:26 PDT 2005
Author: karl
Date: 2005-07-30 10:16:21 -0700 (Sat, 30 Jul 2005)
New Revision: 9656
Modified:
icecast/branches/kh/icecast/conf/icecast.xml.in
icecast/branches/kh/icecast/configure.in
icecast/branches/kh/icecast/src/auth.c
icecast/branches/kh/icecast/src/cfgfile.c
icecast/branches/kh/icecast/src/cfgfile.h
icecast/branches/kh/icecast/src/client.c
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/connection.h
Log:
initial ssl port handling work
Modified: icecast/branches/kh/icecast/conf/icecast.xml.in
===================================================================
--- icecast/branches/kh/icecast/conf/icecast.xml.in 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/conf/icecast.xml.in 2005-07-30 17:16:21 UTC (rev 9656)
@@ -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"
Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/configure.in 2005-07-30 17:16:21 UTC (rev 9656)
@@ -130,6 +130,14 @@
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]),
Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/src/auth.c 2005-07-30 17:16:21 UTC (rev 9656)
@@ -354,6 +354,9 @@
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)
{
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2005-07-30 17:16:21 UTC (rev 9656)
@@ -794,6 +794,11 @@
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 @@
} 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);
Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/src/cfgfile.h 2005-07-30 17:16:21 UTC (rev 9656)
@@ -97,6 +97,7 @@
int port;
char *bind_address;
int shoutcast_compat;
+ int ssl;
} listener_t;
typedef struct ice_config_tag
@@ -147,6 +148,7 @@
char *base_dir;
char *log_dir;
char *pidfile;
+ char *cert_file;
char *webroot_dir;
char *adminroot_dir;
aliases *aliases;
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/src/client.c 2005-07-30 17:16:21 UTC (rev 9656)
@@ -148,15 +148,34 @@
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 @@
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;
}
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/src/connection.c 2005-07-30 17:16:21 UTC (rev 9656)
@@ -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 *_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 @@
_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 @@
{
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 @@
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 @@
}
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 @@
{
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 @@
/* 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 @@
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 @@
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);
}
Modified: icecast/branches/kh/icecast/src/connection.h
===================================================================
--- icecast/branches/kh/icecast/src/connection.h 2005-07-30 17:09:51 UTC (rev 9655)
+++ icecast/branches/kh/icecast/src/connection.h 2005-07-30 17:16:21 UTC (rev 9656)
@@ -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 @@
int serversock;
int error;
+#ifdef HAVE_OPENSSL
+ /* SSL handler */
+ SSL *ssl;
+#endif
char *ip;
char *host;
More information about the commits
mailing list