Commit f59392ef authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Support for re-using the same TLS/SSL httpd hosts for multiple stream ouputs;

a minor TLS httpd API change was needed (closes #92)
parent dcee738b
...@@ -112,8 +112,8 @@ typedef int (*httpd_file_callback_t)( httpd_file_sys_t*, httpd_file_t *, uint8_t ...@@ -112,8 +112,8 @@ typedef int (*httpd_file_callback_t)( httpd_file_sys_t*, httpd_file_t *, uint8_t
*/ */
/* create a new host */ /* 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_HostNew, ( vlc_object_t *, const 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_TLSHostNew, ( vlc_object_t *, const char *, int, const char *, const char *, const char *, const char * ) );
/* delete a host */ /* delete a host */
VLC_EXPORT( void, httpd_HostDelete, ( httpd_host_t * ) ); VLC_EXPORT( void, httpd_HostDelete, ( httpd_host_t * ) );
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <vlc/sout.h> #include <vlc/sout.h>
#include "vlc_httpd.h" #include "vlc_httpd.h"
#include "vlc_tls.h"
#define FREE( p ) if( p ) { free( p); (p) = NULL; } #define FREE( p ) if( p ) { free( p); (p) = NULL; }
...@@ -130,7 +129,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -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_t *p_access = (sout_access_out_t*)p_this;
sout_access_out_sys_t *p_sys; sout_access_out_sys_t *p_sys;
tls_server_t *p_tls;
char *psz_parser, *psz_name; char *psz_parser, *psz_name;
...@@ -140,6 +138,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -140,6 +138,8 @@ static int Open( vlc_object_t *p_this )
char *psz_user = NULL; char *psz_user = NULL;
char *psz_pwd = NULL; char *psz_pwd = NULL;
char *psz_mime = NULL; char *psz_mime = NULL;
const char *psz_cert = NULL, *psz_key = NULL, *psz_ca = NULL,
*psz_crl = NULL;
vlc_value_t val; vlc_value_t val;
if( !( p_sys = p_access->p_sys = if( !( p_sys = p_access->p_sys =
...@@ -200,62 +200,28 @@ static int Open( vlc_object_t *p_this ) ...@@ -200,62 +200,28 @@ static int Open( vlc_object_t *p_this )
/* SSL support */ /* SSL support */
if( p_access->psz_access && !strcmp( p_access->psz_access, "https" ) ) 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_cert = config_GetPsz( p_this, SOUT_CFG_PREFIX"cert" );
psz_key = config_GetPsz( p_this, SOUT_CFG_PREFIX"key" ); psz_key = config_GetPsz( p_this, SOUT_CFG_PREFIX"key" );
psz_ca = config_GetPsz( p_this, SOUT_CFG_PREFIX"ca" );
p_tls = tls_ServerCreate( p_this, psz_cert, psz_key ); psz_crl = config_GetPsz( p_this, SOUT_CFG_PREFIX"crl" );
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;
}
if( i_bind_port <= 0 ) if( i_bind_port <= 0 )
i_bind_port = DEFAULT_SSL_PORT; i_bind_port = DEFAULT_SSL_PORT;
} }
else else
{ {
p_tls = NULL;
if( i_bind_port <= 0 ) if( i_bind_port <= 0 )
i_bind_port = DEFAULT_PORT; i_bind_port = DEFAULT_PORT;
} }
p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access), p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_access),
psz_bind_addr, i_bind_port, psz_bind_addr, i_bind_port,
p_tls ); psz_cert, psz_key, psz_ca,
psz_crl );
if( p_sys->p_httpd_host == NULL ) if( p_sys->p_httpd_host == NULL )
{ {
msg_Err( p_access, "cannot listen on %s:%d", msg_Err( p_access, "cannot listen on %s:%d",
psz_bind_addr, i_bind_port ); psz_bind_addr, i_bind_port );
if( p_tls != NULL )
tls_ServerDelete( p_tls );
free( psz_name ); free( psz_name );
free( psz_file_name ); free( psz_file_name );
free( p_sys ); free( p_sys );
......
...@@ -210,10 +210,10 @@ static int Open( vlc_object_t *p_this ) ...@@ -210,10 +210,10 @@ static int Open( vlc_object_t *p_this )
intf_sys_t *p_sys; intf_sys_t *p_sys;
char *psz_host; char *psz_host;
char *psz_address = ""; 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; int i_port = 0;
char *psz_src; char *psz_src;
tls_server_t *p_tls;
psz_host = config_GetPsz( p_intf, "http-host" ); psz_host = config_GetPsz( p_intf, "http-host" );
if( psz_host ) if( psz_host )
...@@ -259,47 +259,17 @@ static int Open( vlc_object_t *p_this ) ...@@ -259,47 +259,17 @@ static int Open( vlc_object_t *p_this )
psz_cert = config_GetPsz( p_intf, "http-intf-cert" ); psz_cert = config_GetPsz( p_intf, "http-intf-cert" );
if ( psz_cert != NULL ) if ( psz_cert != NULL )
{ {
const char *psz_pem;
msg_Dbg( p_intf, "enablind TLS for HTTP interface (cert file: %s)", msg_Dbg( p_intf, "enablind TLS for HTTP interface (cert file: %s)",
psz_cert ); psz_cert );
psz_pem = config_GetPsz( p_intf, "http-intf-key" ); psz_key = config_GetPsz( p_intf, "http-intf-key" );
psz_ca = config_GetPsz( p_intf, "http-intf-ca" );
p_tls = tls_ServerCreate( p_this, psz_cert, psz_pem ); psz_crl = config_GetPsz( p_intf, "http-intf-crl" );
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;
}
if( i_port <= 0 ) if( i_port <= 0 )
i_port = 8443; i_port = 8443;
} }
else else
{ {
p_tls = NULL;
if( i_port <= 0 ) if( i_port <= 0 )
i_port= 8080; i_port= 8080;
} }
...@@ -307,13 +277,11 @@ static int Open( vlc_object_t *p_this ) ...@@ -307,13 +277,11 @@ static int Open( vlc_object_t *p_this )
msg_Dbg( p_intf, "base %s:%d", psz_address, i_port ); msg_Dbg( p_intf, "base %s:%d", psz_address, i_port );
p_sys->p_httpd_host = httpd_TLSHostNew( VLC_OBJECT(p_intf), psz_address, 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 ) if( p_sys->p_httpd_host == NULL )
{ {
msg_Err( p_intf, "cannot listen on %s:%d", psz_address, i_port ); 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->psz_html_type );
free( p_sys ); free( p_sys );
return VLC_EGENERIC; return VLC_EGENERIC;
......
...@@ -871,21 +871,26 @@ void httpd_StreamDelete( httpd_stream_t *stream ) ...@@ -871,21 +871,26 @@ void httpd_StreamDelete( httpd_stream_t *stream )
static void httpd_HostThread( httpd_host_t * ); static void httpd_HostThread( httpd_host_t * );
/* create a new host */ /* 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 ) 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, httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, const char *psz_hostname,
int i_port, tls_server_t *p_tls ) int i_port,
const char *psz_cert, const char *psz_key,
const char *psz_ca, const char *psz_crl )
{ {
httpd_t *httpd; httpd_t *httpd;
httpd_host_t *host; httpd_host_t *host;
tls_server_t *p_tls;
char *psz_host;
vlc_value_t lockval; vlc_value_t lockval;
int i; int i;
psz_host = strdup( psz_host ); psz_host = strdup( psz_hostname );
if( psz_host == NULL ) if( psz_host == NULL )
{ {
msg_Err( p_this, "memory error" ); msg_Err( p_this, "memory error" );
...@@ -903,6 +908,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host, ...@@ -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 ) if( ( httpd = vlc_object_create( p_this, VLC_OBJECT_HTTPD ) ) == NULL )
{ {
vlc_mutex_unlock( lockval.p_address ); vlc_mutex_unlock( lockval.p_address );
free( psz_host );
return NULL; return NULL;
} }
...@@ -918,12 +924,10 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host, ...@@ -918,12 +924,10 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
{ {
host = httpd->host[i]; host = httpd->host[i];
/* FIXME : Cannot re-use host if it uses TLS/SSL */ /* cannot mix TLS and non-TLS hosts */
if( httpd->host[i]->p_tls != NULL ) if( ( ( httpd->host[i]->p_tls != NULL ) != ( psz_cert != NULL ) )
continue; || ( host->i_port != i_port )
|| strcmp( host->psz_hostname, psz_hostname ) )
if( ( host->i_port != i_port )
|| strcmp( host->psz_hostname, psz_host ) )
continue; continue;
/* yep found */ /* yep found */
...@@ -933,6 +937,33 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host, ...@@ -933,6 +937,33 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
return 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 */ /* create the new host */
host = vlc_object_create( p_this, sizeof( httpd_host_t ) ); host = vlc_object_create( p_this, sizeof( httpd_host_t ) );
host->httpd = httpd; host->httpd = httpd;
...@@ -971,6 +1002,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host, ...@@ -971,6 +1002,7 @@ httpd_host_t *httpd_TLSHostNew( vlc_object_t *p_this, char *psz_host,
return host; return host;
error: error:
free( psz_host );
if( httpd->i_host <= 0 ) if( httpd->i_host <= 0 )
{ {
vlc_object_release( httpd ); vlc_object_release( httpd );
...@@ -986,6 +1018,9 @@ error: ...@@ -986,6 +1018,9 @@ error:
vlc_object_destroy( host ); vlc_object_destroy( host );
} }
if( p_tls != NULL )
tls_ServerDelete( p_tls );
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment