Support for re-using the same TLS/SSL httpd hosts for multiple stream ouputs;
authorRémi Denis-Courmont <rem@videolan.org>
Sun, 22 May 2005 15:03:47 +0000 (15:03 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Sun, 22 May 2005 15:03:47 +0000 (15:03 +0000)
a minor TLS httpd API change was needed (closes #92)

include/vlc_httpd.h
modules/access_output/http.c
modules/control/http.c
src/misc/httpd.c

index 5935933..aa04c76 100644 (file)
@@ -112,8 +112,8 @@ typedef int (*httpd_file_callback_t)( httpd_file_sys_t*, httpd_file_t *, uint8_t
 */
 
 /* create a new host */
-VLC_EXPORT( httpd_host_t *, httpd_HostNew, ( vlc_object_t *, char *psz_host, int i_port ) );
-VLC_EXPORT( httpd_host_t *, httpd_TLSHostNew, ( vlc_object_t *, char *, int, tls_server_t * ) );
+VLC_EXPORT( httpd_host_t *, httpd_HostNew, ( vlc_object_t *, const char *psz_host, int i_port ) );
+VLC_EXPORT( httpd_host_t *, httpd_TLSHostNew, ( vlc_object_t *, const char *, int, const char *, const char *, const char *, const char * ) );
 
 /* delete a host */
 VLC_EXPORT( void,           httpd_HostDelete, ( httpd_host_t * ) );
index 0de31cf..8555030 100644 (file)
@@ -30,7 +30,6 @@
 #include <vlc/sout.h>
 
 #include "vlc_httpd.h"
-#include "vlc_tls.h"
 
 #define FREE( p ) if( p ) { free( p); (p) = NULL; }
 
@@ -130,7 +129,6 @@ static int Open( vlc_object_t *p_this )
 {
     sout_access_out_t       *p_access = (sout_access_out_t*)p_this;
     sout_access_out_sys_t   *p_sys;
-    tls_server_t            *p_tls;
 
     char                *psz_parser, *psz_name;
 
@@ -140,6 +138,8 @@ static int Open( vlc_object_t *p_this )
     char                *psz_user = NULL;
     char                *psz_pwd = NULL;
     char                *psz_mime = NULL;
+    const char          *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL,
+                        *psz_crl = NULL;
     vlc_value_t         val;
 
     if( !( p_sys = p_access->p_sys =
@@ -200,62 +200,28 @@ static int Open( vlc_object_t *p_this )
     /* SSL support */
     if( p_access->psz_access && !strcmp( p_access->psz_access, "https" ) )
     {
-        const char *psz_cert, *psz_key;
         psz_cert = config_GetPsz( p_this, SOUT_CFG_PREFIX"cert" );
         psz_key = config_GetPsz( p_this, SOUT_CFG_PREFIX"key" );
-
-        p_tls = tls_ServerCreate( p_this, psz_cert, psz_key );
-        if ( p_tls == NULL )
-        {
-            msg_Err( p_this, "TLS initialization error" );
-            free( psz_file_name );
-            free( psz_name );
-            free( p_sys );
-            return VLC_EGENERIC;
-        }
-
-        psz_cert = config_GetPsz( p_this, SOUT_CFG_PREFIX"ca" );
-        if ( ( psz_cert != NULL) && tls_ServerAddCA( p_tls, psz_cert ) )
-        {
-            msg_Err( p_this, "TLS CA error" );
-            tls_ServerDelete( p_tls );
-            free( psz_file_name );
-            free( psz_name );
-            free( p_sys );
-            return VLC_EGENERIC;
-        }
-
-        psz_cert = config_GetPsz( p_this, SOUT_CFG_PREFIX"crl" );
-        if ( ( psz_cert != NULL) && tls_ServerAddCRL( p_tls, psz_cert ) )
-        {
-            msg_Err( p_this, "TLS CRL error" );
-            tls_ServerDelete( p_tls );
-            free( psz_file_name );
-            free( psz_name );
-            free( p_sys );
-            return VLC_EGENERIC;
-        }
+        psz_ca = config_GetPsz( p_this, SOUT_CFG_PREFIX"ca" );
+        psz_crl = config_GetPsz( p_this, SOUT_CFG_PREFIX"crl" );
 
         if( i_bind_port <= 0 )
             i_bind_port = DEFAULT_SSL_PORT;
     }
     else
     {
-        p_tls = NULL;
         if( i_bind_port <= 0 )
             i_bind_port = DEFAULT_PORT;
     }
 
     p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access),
                                             psz_bind_addr, i_bind_port,
-                                            p_tls );
+                                            psz_cert, psz_key, psz_ca,
+                                            psz_crl );
     if( p_sys->p_httpd_host == NULL )
     {
         msg_Err( p_access, "cannot listen on %s:%d",
                  psz_bind_addr, i_bind_port );
-
-        if( p_tls != NULL )
-            tls_ServerDelete( p_tls );
         free( psz_name );
         free( psz_file_name );
         free( p_sys );
index 54b8280..e4ce72a 100644 (file)
@@ -210,10 +210,10 @@ static int Open( vlc_object_t *p_this )
     intf_sys_t    *p_sys;
     char          *psz_host;
     char          *psz_address = "";
-    const char    *psz_cert;
+    const char    *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL,
+                  *psz_crl = NULL;
     int           i_port       = 0;
     char          *psz_src;
-    tls_server_t  *p_tls;
 
     psz_host = config_GetPsz( p_intf, "http-host" );
     if( psz_host )
@@ -259,47 +259,17 @@ static int Open( vlc_object_t *p_this )
     psz_cert = config_GetPsz( p_intf, "http-intf-cert" );
     if ( psz_cert != NULL )
     {
-        const char *psz_pem;
-
         msg_Dbg( p_intf, "enablind TLS for HTTP interface (cert file: %s)",
                  psz_cert );
-        psz_pem = config_GetPsz( p_intf, "http-intf-key" );
-
-        p_tls = tls_ServerCreate( p_this, psz_cert, psz_pem );
-        if ( p_tls == NULL )
-        {
-            msg_Err( p_intf, "TLS initialization error" );
-            free( p_sys->psz_html_type );
-            free( p_sys );
-            return VLC_EGENERIC;
-        }
-
-        psz_pem = config_GetPsz( p_intf, "http-intf-ca" );
-        if ( ( psz_pem != NULL) && tls_ServerAddCA( p_tls, psz_pem ) )
-        {
-            msg_Err( p_intf, "TLS CA error" );
-            tls_ServerDelete( p_tls );
-            free( p_sys->psz_html_type );
-            free( p_sys );
-            return VLC_EGENERIC;
-        }
-
-        psz_pem = config_GetPsz( p_intf, "http-intf-crl" );
-        if ( ( psz_pem != NULL) && tls_ServerAddCRL( p_tls, psz_pem ) )
-        {
-            msg_Err( p_intf, "TLS CRL error" );
-            tls_ServerDelete( p_tls );
-            free( p_sys->psz_html_type );
-            free( p_sys );
-            return VLC_EGENERIC;
-        }
+        psz_key = config_GetPsz( p_intf, "http-intf-key" );
+        psz_ca = config_GetPsz( p_intf, "http-intf-ca" );
+        psz_crl = config_GetPsz( p_intf, "http-intf-crl" );
 
         if( i_port <= 0 )
             i_port = 8443;
     }
     else
     {
-        p_tls = NULL;
         if( i_port <= 0 )
             i_port= 8080;
     }
@@ -307,13 +277,11 @@ static int Open( vlc_object_t *p_this )
     msg_Dbg( p_intf, "base %s:%d", psz_address, i_port );
 
     p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_intf), psz_address,
-                                            i_port, p_tls );
+                                            i_port, psz_cert, psz_key, psz_ca,
+                                            psz_crl );
     if( p_sys->p_httpd_host == NULL )
     {
         msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port );
-        if ( p_tls != NULL )
-            tls_ServerDelete( p_tls );
-
         free( p_sys->psz_html_type );
         free( p_sys );
         return VLC_EGENERIC;
index 5f87b54..c06d365 100644 (file)
@@ -871,21 +871,26 @@ void httpd_StreamDelete( httpd_stream_t *stream )
 static void httpd_HostThread( httpd_host_t * );
 
 /* create a new host */
-httpd_host_t *httpd_HostNew( vlc_object_t *p_this, char *psz_host,
+httpd_host_t *httpd_HostNew( vlc_object_t *p_this, const char *psz_host,
                              int i_port )
 {
-    return httpd_TLSHostNew( p_this, psz_host, i_port, NULL );
+    return httpd_TLSHostNew( p_this, psz_host, i_port, NULL, NULL, NULL, NULL
+                           );
 }
 
-httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
-                                int i_port, tls_server_t *p_tls )
+httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
+                                int i_port,
+                                const char *psz_cert, const char *psz_key,
+                                const char *psz_ca, const char *psz_crl )
 {
     httpd_t      *httpd;
     httpd_host_t *host;
+    tls_server_t *p_tls;
+    char *psz_host;
     vlc_value_t  lockval;
     int i;
 
-    psz_host = strdup( psz_host );
+    psz_host = strdup( psz_hostname );
     if( psz_host == NULL )
     {
         msg_Err( p_this, "memory error" );
@@ -903,6 +908,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
         if( ( httpd = vlc_object_create( p_this, VLC_OBJECT_HTTPD ) ) == NULL )
         {
             vlc_mutex_unlock( lockval.p_address );
+            free( psz_host );
             return NULL;
         }
 
@@ -918,12 +924,10 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
     {
         host = httpd->host[i];
 
-        /* FIXME : Cannot re-use host if it uses TLS/SSL */
-        if( httpd->host[i]->p_tls != NULL )
-            continue;
-
-        if( ( host->i_port != i_port )
-         || strcmp( host->psz_hostname, psz_host ) )
+        /* cannot mix TLS and non-TLS hosts */
+        if( ( ( httpd->host[i]->p_tls != NULL ) != ( psz_cert != NULL ) )
+         || ( host->i_port != i_port )
+         || strcmp( host->psz_hostname, psz_hostname ) )
             continue;
 
         /* yep found */
@@ -933,6 +937,33 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
         return host;
     }
 
+    host = NULL;
+
+    /* determine TLS configuration */
+    if ( psz_cert != NULL )
+    {
+        p_tls = tls_ServerCreate( p_this, psz_cert, psz_key );
+        if ( p_tls == NULL )
+        {
+            msg_Err( p_this, "TLS initialization error" );
+            goto error;
+        }
+
+        if ( ( psz_ca != NULL) && tls_ServerAddCA( p_tls, psz_ca ) )
+        {
+            msg_Err( p_this, "TLS CA error" );
+            goto error;
+        }
+
+        if ( ( psz_crl != NULL) && tls_ServerAddCRL( p_tls, psz_crl ) )
+        {
+            msg_Err( p_this, "TLS CRL error" );
+            goto error;
+        }
+    }
+    else
+        p_tls = NULL;
+
     /* create the new host */
     host = vlc_object_create( p_this, sizeof( httpd_host_t ) );
     host->httpd = httpd;
@@ -971,6 +1002,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
     return host;
 
 error:
+    free( psz_host );
     if( httpd->i_host <= 0 )
     {
         vlc_object_release( httpd );
@@ -986,6 +1018,9 @@ error:
         vlc_object_destroy( host );
     }
 
+    if( p_tls != NULL )
+        tls_ServerDelete( p_tls );
+
     return NULL;
 }