[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